Reputation: 241
As the subject suggests, even if publishing with "--self-contained true" (and with a specific -r option), the runtime still asks for missing .net installation.
I've now studied the subject and it seems to me that pretty much all the related dlls should be in the output folder, but for some reason the mechanism that tries to discover those is not finding them. This can be seen in the trace log that is applied as instructed here:
https://github.com/dotnet/runtime/blob/main/docs/design/features/host-tracing.md
Below is a section of the trace:
Resolving FX directory, name 'Microsoft.NETCore.App' version '6.0.0'
Multilevel lookup is true
Searching FX directory in [C:\Program Files\My Application]
Attempting FX roll forward starting from version='[6.0.0]', apply_patches=1, version_compatibility_range=minor, roll_to_highest_version=0, prefer_release=1
'Roll forward' enabled with version_compatibility_range [minor]. Looking for the lowest release greater than or equal version to [6.0.0]
No match greater than or equal to [6.0.0] found.
'Roll forward' enabled with version_compatibility_range [minor]. Looking for the lowest release/pre-release greater than or equal version to [6.0.0]
No match greater than or equal to [6.0.0] found.
Framework reference didn't resolve to any available version.
Searching FX directory in [C:\Program Files\dotnet]
I have even tried to copy all the same files that would exist in the corresponding C:\Program Files\dotnet\shared... to my publish folder with no better result.
My main question is that what is the mechanism for the .NET to find the dlls? from the publish folder. Why it doesn't find them there but finds them in the C:\Program Files\dotnet\shared...
Upvotes: 10
Views: 8230
Reputation: 54
You do need to use Publish, but you need to set the Deployment mode, in the Publish, screen after clicking Show all settings
, to Self-contained and under File publish options
: enable Produce single file
and enable ReadyToRun compilation
Upvotes: 0
Reputation: 583
Another workaround is to add <SelfContained>true</SelfContained>
into the csproj instead of specifying --self-contained true in the dotnet build & dotnet publish.
Upvotes: 4
Reputation: 535
I also ran into this when I upgraded to .NET 8.0. If you use the --no-build
parameter, you should also specify --self-contained
on dotnet build
as well. This is especially important after .NET 8.0, which introduced a breaking change where runtime specific apps are no longer self-contained by default.
Link to the breaking change: https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/8.0/runtimespecific-app-default
In conclusion:
dotnet build --self-contained
will build your executable as a self-contained app
dotnet publish --self-contained
will copy over the .NET Core runtime files to your publish directory (e.g. 'Microsoft.AspNetCore.dll', 'System.Core.dll', 'System.Console.dll', etc)
You need both to have a working self-contained application.
Upvotes: 7
Reputation: 241
So obviously I did spent some more hours studying this.
It looks to me that one of the reasons why above thing happens is the fact that I'm using dotnet publish --no-build option, and building separately with msbuild. I don't have hard evidence for this, but something similar was suggested somewhere when I was going through about gazillion of different google search results.
But nevertheless, I did manage to get the deployment working (meaning that the global .NET installations were not required). The cure was to remove the two files from the publish output folder:
After that the runtime will seek the .NET assemblies as self-contained. It was actually mentioned in this article that the *.runtimeconfig.json is ONLY for framework-dependent. What did remain as a mystery is that why the dotnet publish copied that one into the output folder. But as mentined above, I'm suspecting the --no-build option to be somehow related.
Upvotes: 9