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...
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With