Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to publish a self-contained C# executable that references another executable?

Tags:

c#

.net

I have two C# .NET 5 projects, let's call them A and B. Both are executables (not DLLs). Project A references project B. I would like to publish project A as a self-contained executable (though not single-file, if that matters). I'm using this command to kick off the publishing process:

dotnet publish A.csproj -c Release --self-contained -r win-x64 /p:PublishTrimmed=true /p:PublishReadyToRun=true

However, this produces the following error when attempting to build project B (which is required since project A references it):

error NETSDK1031: It is not supported to build or publish a self-contained application without specifying a RuntimeIdentifier. You must either specify a RuntimeIdentifier or set SelfContained to false.

But as you can see, I am (I think?) specifying a runtime identifier with -r win-x64. I'm guessing that the runtime identifier that I've specified on the command-line isn't getting passed through when building project B. How can I fix this without disabling SelfContained?

My dotnet version is:

dotnet --version
5.0.400

EDIT: I do not want to put <RuntimeIdentifier>win-x64</RuntimeIdentifier> in my project files because I need to build for multiple different runtimes and I want to be able to control that via the command line.

like image 638
Walt D Avatar asked Oct 15 '22 20:10

Walt D


1 Answers

Thanks to a couple of comments in this Github issue, I was able to figure out how to get it to compile:

  1. Remove the --self-contained flag from the command-line. (According to the docs, "Default is true if a runtime identifier is specified and the project is an executable project (not a library project).")

  2. Add /p:ValidateExecutableReferencesMatchSelfContained=false to the command-line. This was required to suppress the error: "The referenced project 'B.csproj' is a non self-contained executable. A non self-contained executable cannot be referenced by a self-contained executable."

  3. If you want to be able to run the B.exe file that was generated while building project A, you'll need to add an appropriate B.deps.json file to the build output. The easiest way I've found to do this is to make a separate self-contained build of B and then simply copy over the B.deps.json file from it. (And if you're building with PublishTrimmed as I am, then you may need to add entries into your TrimmerRoots.xml file to prevent code needed by project B from getting trimmed from the output.)

After doing these two things, my project is now building and running successfully. I have verified that it still works even on a machine that does not have the .NET Runtime installed and thus the build really is self-contained as desired.

like image 153
Walt D Avatar answered Oct 21 '22 21:10

Walt D