Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two self-contained apps targetting different runtimes #46990

Closed
Jmales opened this issue Jan 14, 2021 · 18 comments
Closed

Two self-contained apps targetting different runtimes #46990

Jmales opened this issue Jan 14, 2021 · 18 comments
Labels
area-Host untriaged New issue has not been triaged by the area owner

Comments

@Jmales
Copy link

Jmales commented Jan 14, 2021

I have a self-contained app (App1) targeting .NET 5.0.1 which is packed alongside another self-contained app (AppFull) targeting .NET 5.0.2. I was expecting everything to work well, but I get several errors with wrong .dll versions when running AppFull (which uses App1):

Description: A .NET application failed.
Application: App1.exe
Path: C:\Tests\AppFull\App1.exe
Message: Error:
  An assembly specified in the application dependencies manifest (App1.deps.json) was not found:
    package: 'runtimepack.Microsoft.NETCore.App.Runtime.win-x64', version: '5.0.1'
    path: 'mscordaccore_amd64_amd64_5.0.120.57516.dll'

Runtimeconfig.json of App1

{
  "runtimeOptions": {
    "tfm": "net5.0",
    "frameworks": [
      {
        "name": "Microsoft.NETCore.App",
        "version": "5.0.1"
      }
    ]
  }
}

Runtimeconfig of AppFull

{
  "runtimeOptions": {
    "tfm": "net5.0",
    "frameworks": [
      {
        "name": "Microsoft.NETCore.App",
        "version": "5.0.2"
      }
    ]
  }
}

And looking at the deps.json files I can see that the system versions are different. App1 has fileVersion 5.0.120.57516 for Microsoft.CSharp.dll, while AppFull has fileVersion 5.0.220.61120 which seems to me that it's the root cause of my problem.

I also tried what's suggested in Framework version resolution but it doesn't seem to work.

What's the best way to solve this problem? I was trying to avoid modifying App1.deps.json manually

@dotnet-issue-labeler dotnet-issue-labeler bot added area-Host untriaged New issue has not been triaged by the area owner labels Jan 14, 2021
@ghost
Copy link

ghost commented Jan 14, 2021

Tagging subscribers to this area: @vitek-karas, @agocke
See info in area-owners.md if you want to be subscribed.

Issue Details

I have a self-contained app (App1) targeting .NET 5.0.1 which is packed alongside another self-contained app (AppFull) targeting .NET 5.0.2. I was expecting everything to work well, but I get several errors with wrong .dll versions when running AppFull (which uses App1):

Description: A .NET application failed.
Application: App1.exe
Path: C:\Tests\AppFull\App1.exe
Message: Error:
  An assembly specified in the application dependencies manifest (App1.deps.json) was not found:
    package: 'runtimepack.Microsoft.NETCore.App.Runtime.win-x64', version: '5.0.1'
    path: 'mscordaccore_amd64_amd64_5.0.120.57516.dll'

Runtimeconfig.json of App1

{
  "runtimeOptions": {
    "tfm": "net5.0",
    "frameworks": [
      {
        "name": "Microsoft.NETCore.App",
        "version": "5.0.1"
      }
    ]
  }
}

Runtimeconfig of AppFull

{
  "runtimeOptions": {
    "tfm": "net5.0",
    "frameworks": [
      {
        "name": "Microsoft.NETCore.App",
        "version": "5.0.2"
      }
    ]
  }
}

And looking at the deps.json files I can see that the system versions are different. App1 has fileVersion 5.0.120.57516 for Microsoft.CSharp.dll, while AppFull has fileVersion 5.0.220.61120 which seems to me that it's the root cause of my problem.

I also tried what's suggested in Framework version resolution but it doesn't seem to work.

What's the best way to solve this problem? I was trying to avoid modifying App1.deps.json manually

Author: Jmales
Assignees: -
Labels:

area-Host, untriaged

Milestone: -

@vitek-karas
Copy link
Member

Could you please clarify what you mean by "pack alongside"?
I assume you build both apps with --self-contained (or with -r something), this will produce two directories with lot of files in each. Do you somehow try to "merge" the two?

Also the runtime configs above are for framework dependent apps, not for self-contained apps... (not that it matters for the versions).

Which part of the Framework version resolution document did you try to use (there's lot of stuff in that topic).

@Jmales
Copy link
Author

Jmales commented Jan 15, 2021

Thanks for the answer!

Could you please clarify what you mean by "pack alongside"?
I assume you build both apps with --self-contained (or with -r something), this will produce two directories with lot of files in each. Do you somehow try to "merge" the two?

Yes, that's basically it. I copy the contents of App1 into AppFull. Is there any better way of achieving this?

Which part of the Framework version resolution document did you try to use (there's lot of stuff in that topic).

I tried the rollForward option in runtimeconfig.json, as I was trying to achieve a rollForward strategy when system tries to run App1 with 5.0.1. I wanted somehow that it understood that instead of 5.0.1it can also run with LatestPatch, 5.0.2.

@Jmales
Copy link
Author

Jmales commented Jan 15, 2021

You state that the runtimeconfigare for framework dependent apps, not for self--contained. Why are these files generated then when I publish a self-contained app?

@vitek-karas
Copy link
Member

In short this is currently an unsupported scenario - the story is basically: whatever SDK produces, should work, if you make changes to the output of SDK it might break.

For most assemblies and files this will work because the file names didn't change and the .deps.json has version info to help with resolving conflicts. But in the case of mscordaccore_amd64_amd64_5.0.120.57516.dll the version is baked into the file name, and so one of the .deps.json files will have a link to a file which is not there.

It should mostly work if you make sure both apps are published with the exact same framework version. You will still have to deal with any versioning issues between NuGets and other dependencies of the two apps though. Note that some other features will become next to impossible to get working - for example PublishTrimmed=true is just not going to work.

@Jmales
Copy link
Author

Jmales commented Jan 15, 2021

So, in this scenario, do you know any other approach better than mine (i.e. copy one self-contained app to the contents of other) ?

Thanks for the info so far

@vitek-karas
Copy link
Member

You might be able to get something slightly better if there's a project reference between the two apps. As per this PR dotnet/sdk#14488 SDK might be able to handle at least some situations.

@Jmales
Copy link
Author

Jmales commented Jan 15, 2021

👍

One final doubt. I noticed that running AppFull in Windows results in the errors referred above but running that same AppFull in Mac does not. Any idea on why?

@vitek-karas
Copy link
Member

I honestly don't know, there only seems to be mscordaccore library on OSX, not a counterpart of mscordaccore_amd64_amd64_5.0.120.57516 from windows - @dotnet/dotnet-diag might be able to explain the intricacies of debugger support libraries across platforms.

@mikem8361
Copy link
Member

The names of the debugger support modules (DAC,DBI) are Windows: both mscordaccore.dll/mscordbi.dll and modules like mscordaccore_amd64_amd64_5.0.120.57516, Linux: libmscordaccore.so/libmscordbi.so, MacOS: libmscordaccore.dylib, libmscorlib.dylib.

The DAC modules mscordaccore_amd64_amd64_5.0.120.57516 are basically that runtime's version of mscordaccore.dll but decorated with the "host" architecture, "target" architecture and runtime version. This naming allows the Windows debuggers to download cross-architecture DACs (i.e. download the arm64 target DAC that runs on x64).

I don't know all the ins and outs of self-contained apps, but I assume they built for and target specific OSes and architectures. If "AppFull" is only built for "win-x64" and it is run on "MacOS" you may see problems like this.

@Jmales
Copy link
Author

Jmales commented Jan 18, 2021

I don't know all the ins and outs of self-contained apps, but I assume they built for and target specific OSes and architectures. If "AppFull" is only built for "win-x64" and it is run on "MacOS" you may see problems like this.

@mikem8361 No, AppFull and App1 were built for both "win-x64" and "osx-x64".

Ultimately we were following a Single-File publish approach of App1 to solve the problem, and while debugging everything seemed solved. However, because of #3671 we cannot sign the App1 bundle and hence this isn't a workaround as well.

New ideas are welcome.

@agocke
Copy link
Member

agocke commented Jan 19, 2021

@Jmales Why do you want to put both apps in the same directory? It's not clear to me what problem you're trying to solve.

@Jmales
Copy link
Author

Jmales commented Jan 19, 2021

@agocke initially we wanted to put both on the same directory since they both use some shared .dylib/.dll. We were trying to save some space.

However, that was a problem due to the 2 .runtimeconfig.json when built against different .NET versions (problem was only in Windows for some reason). The problem was the reported in the initial post.

We gave up on trying to save space and we invested some time in having App1 published as a Single-file inside AppFull. That solved our problem, however the signing process in Mac was a blocker.

Ultimately (today) we ended up having a self-contained App1 inside a sub-directory of AppFull which seems to do it. We have a lot of repeated .dlls/.dylibs but that seems to be the only method that works at the moment.

@andyfriedman
Copy link

andyfriedman commented May 21, 2021

This is super annoying because the mscordaccore_amd64_amd64_* dll is literally the only dll in the published output that has a version number on it. And because the file name can vary depending on which machine it was built on it breaks other processes, like building installers and nuget packages that rely on a static list of file names. Running the app without that file doesn't seem to be an option so is there another solution? It would be a real hack to have to write a script to change the file name and the reference in deps.json.

@vitek-karas
Copy link
Member

If the two apps are not built against the same exact version, there's absolutely no guarantee that when you copy them over each other it will work anyway. So the version mismatch is in a way a good thing.

In short, this is not a scenario which is currently supported and so it's not expected to work.

What is supported is sharing a private runtime between the apps, but sometimes this is not very friendly (the functionality to make it friendly is currently missing): #52974 (comment)

@mikem8361
Copy link
Member

It sounds like the problem is that the "long" named DAC is referenced in *deps.json. It doesn't need to be. It is used by SOS/debuggers and not directly by the runtime itself. It may not even need to be part of the self-contained app since those SOS/debugger can usually (even for private or nightly builds) download it for a specific runtime version.

@hoyosjs
Copy link
Member

hoyosjs commented May 21, 2021

Even if the file is removed, this is not a supported scenario. There's quite a bit of logic in nuget reference resolution that gets stomped over by this. In this method of munging folders together you'd need a way to only copy the highest assembly version and such. The roll-forward is not guaranteed to work for example, but it most likely will work. The problem is with references to DLLs in packages and the transitive closure resolution.

@agocke
Copy link
Member

agocke commented Jun 7, 2021

Closing in favor of #53834

@agocke agocke closed this as completed Jun 7, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jul 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Host untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

No branches or pull requests

6 participants