Publishing a solution with 6.0 exe and 3.1 classlib to the same target path produces a corrupted output
See original GitHub issueDescription
I created a .NET 6.0 C# project that referenced a .NET Core 3.1 project, published it as a self-contained application and tried to run it on a Linux server, but it threw the FileLoadException below. It turns out it’s not even necessary to reference the .NET 3.1 project - it’s enough for it to be included in the solution.
Reproduction Steps
Extract repro.zip and in the repro directory (where repro.sln is) run:
dotnet publish --nologo -c Release --self-contained -r linux-x64 -o bin/pub-linux
cd bin/pub-linux
./repro
(I originally ran it on a remote server, but the problem still reproduces on the same machine where .NET SDK is installed.)
Expected behavior
The application runs and prints “It ran! (DATE/TIME)”
Actual behavior
System.IO.FileLoadException: Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest definition does not match the assembly reference. (0x80131040)
File name: 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Regression?
Don’t know.
Known Workarounds
It works when not building a self-contained application (but of course then the runtime has to be installed on the target server).
Configuration
Happens on Ubuntu 18.04.6 and Linux Mint 20 (based on Ubuntu 20.04), both x64.
$ dotnet --info .NET SDK (reflecting any global.json): Version: 6.0.202 Commit: f8a55617d2
Runtime Environment: OS Name: ubuntu OS Version: 18.04 OS Platform: Linux RID: ubuntu.18.04-x64 Base Path: /usr/share/dotnet/sdk/6.0.202/
Host (useful for support): Version: 6.0.4 Commit: be98e88c76
.NET SDKs installed: 6.0.202 [/usr/share/dotnet/sdk]
.NET runtimes installed: Microsoft.AspNetCore.App 6.0.4 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 6.0.4 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Other information
dotnet publish
appears to change which runtime DLLs are included depending on whether the .NET Core 3.1 project is referenced or not, so I’m guessing that the 3.1 version of System.Runtime.dll is getting mixed in somehow. Oddly, this only seems to happen when the .NET Core 3.1 project is outside the solution directory (as it is in the attached repro).
Issue Analytics
- State:
- Created a year ago
- Comments:11 (6 by maintainers)
Top GitHub Comments
@loop-evgeny I moved the issue to the sdk repo (since this is a build-time problem) and updated the title to better match what’s going on.
As a workaround - run publish on a project directly, not on the solution (or directory in this case), that should make it work.
There’s something really weird going on. The files are a combination of .NBT 6 (the app, native bits of the runtime like libcoreclr.so), .NET Core 3.1 (most of the System.* assemblies) and .NET Framework 4.* (some of the System.* assemblies, for example System.Runtime.dll).
It seems that running
dotnet publish
in a directory which has an.sln
file will publish that solution. But if you also specify-o path
all of the projects in the solution will be published to the same output directory. Combine that with the fact thatdotnet publish --self-contained
on a classlib project (the .NET 3.1 project is a classlib - it doesn’t haveOutputType=exe
) is effectively undefined behavior (I know… I’ve been complaining about this for a while), it produces a really weird output where some assemblies are 3.1 and some are 4.* - no idea how.In short if the two projects are published in the wrong order (the console app first, then the 3.1 reference) it will produce basically garbage in the output folder.
If you run
dotnet publish consoleproj.csproj
then it will only build that one app and everything seems to work correctly. In my case I didn’t get a repro because first I didn’t try with-o path
(didn’t seem important) and later when I did use it, I got lucky and it built the 3.1 first and then the consoleproj which overwrote everything with version 6.