Self-Contained publish with multiple executables?
See original GitHub issueI hope I am posting this in the right place since I’m currently using dotnet 3.1 which is in the dotnet/cli repo, but that repo has removed it’s issue tracker.
I maintain an auto-updating application where external runtimes are a hazard that has cost us a lot of time and expense over the last 10 years. We are moving to a self contained build to finally leave this behind us. But our application is a bundle of several executables: a windows service, a UI agent, a handful of testing tools for users, some shims for loading other things. They cannot simply be put together into one exe and have their functionality switched by arguments because it’s a mixture of winforms and cli, as well as the fact that several exes need to be easily found/run by users.
I have not been able to find any supported, official mechanism to create a self contained build of multiple projects/executables together, where the union of their dependencies are included and trimmed. If there is an official, proper way to do this and I’ve missed it, someone please tell me. I have however found a very easy workaround to “trick” the SDK into doing this:
- Create a dummy exe project (I call it BuildHelper)
- Add all the other exe projects as references to the BuildHelper project, like they were dlls
- Publish the BuildHelper project, self contained and trimmed
- Delete the BuildHelper project, dll/exe from the output
This workaround for the most part works very well. If I were to make independent self contained builds of all the exes separately, the output would total well over a gigabyte, because of all the duplicated runtime overhead, which is not acceptable for my purposes. Building in the way described above produces a single self contained runtime with the multiple exes in it for around 90mb, which zips down to about 45mb. Two takeaways, 1. you can see this is a very useful thing to be able to do, 2. as simple as this workaround is, there shouldn’t be much technical challenge to providing this feature out of the box so that this dance would not be necessary. It is my hope that something like this can be provided/supported in the future.
Since it is not (I don’t think) currently supported, there are a few oddities with it. For one thing I have not gotten it to work on dotnet 5, although I have not spent much time trying, but there is some funniness with the inclusion of deps.json files (maybe the tip an iceberg). More relevantly to me at the moment, although normal 64 bit builds work fine, when I try to make a build that is 32 bit (by specifying -r win-x86 when publishing BuildHelper), it doesn’t work. If I leave the BuildHelper files in the output, I can run that successfully on a 32 bit machine. But if I try to run any of the other included (built as dependencies) exes on a 32 bit machine, I get errors that look like they are built for 64 bit, even though the publish folder is full of only x86 dlls.
Running the exes on a 32 bit machine gives the output
Program 'MyApp.exe' failed to run: The specified executable is not a valid application for this OS
I wonder if for some reason it is including 64-bit exe-shims with the 32bit trimmed dlls for the sub-applications…
Also if I try to run the 32 bit exes on a 64 bit machine I get the output
The library hostfxr.dll was found, but loading it from C:\temp\32client\hostfxr.dll failed
- Installing .NET Core prerequisites might help resolve this problem. https://go.microsoft.com/fwlink/?linkid=798306
Another oddity with the 32 bit build is that the nuget package for webview2 includes the 64bit native libraries, rather than the 32 bit ones. So it seems like the sdk is somehow not fully getting the message that the “dependency exes” (and not just BuildHelper) are being published as win-x86.
Is there a supported way to do what I’m trying to do? If not, can I request such a feature? Also any thoughts about the 32bit build situation above are welcome.
Issue Analytics
- State:
- Created 2 years ago
- Comments:12 (5 by maintainers)
Top GitHub Comments
It’s “link” versus “copy” (copyused is now sort of deprecated) - the property is
TrimMode
- if you don’t set that, you’re should be OK.Appreciate the clarification!