Repository navigation
Publish self-contained .NET 5 application #3407
Description
Activity
- changed the title
[-]Publish .NET 5 self-contained application[/-][+]Publish self-contained .NET 5 application[/+]on Feb 16, 2021 - Change
CefSharp.MinimalExample.Wpf.csprojtarget framework tonet5.0-windows
Does it work if you publish leaving the
TargetFrameworkunchanged? (Publish fornetcoreapp3.1).The
BrowserSubprocessis actually anetcoreapp3.1exe with<RollForward>Major</RollForward>specified so it should run with a newer.Net 5runtime installed. In my limited testing this workings when using the installed runtime. I suspect (though haven't done any testing) that it's not working when self contained, possibly the framework version used is trimmed down and missing pieces required for the rollforward.For this use case I expect you'll need to self host the
BrowserSubprocessusing your apps own exe. See https://github.com/cefsharp/CefSharp/blob/cefsharp/87/CefSharp.Core/BrowserSubprocess/SelfHost.cs#L26Whilst I understand this is a little harder for
WPFas there's noMainby default, it's pretty trivial to add one.There are some linker errors trying to compile the
VC++projects targetingnet5.0so there's no way to currently build a full set ofnet5.0libraries. (This will likely need to be raised withMS).- Change
Does it work if you publish leaving the TargetFramework unchanged? (Publish for netcoreapp3.1).
I will test.
For this use case I expect you'll need to self host the BrowserSubprocess using your apps own exe. See https://github.com/cefsharp/CefSharp/blob/cefsharp/87/CefSharp.Core/BrowserSubprocess/SelfHost.cs#L26
Great! Then that is an acceptable solution for me.
Thank you :)
I also ran into an issue publishing with self-contained selected using CefSharp.Winforms.NETCore 87.1.132.
I first tried publishing with my own application with target framework of net5.0-windows. When running my published executable, the window opens, but the page does not load and my mouse pointer constantly toggles the loading icon on/off.
I then tried publishing the minimal example that targets netcoreapp3.1 with self-contained selected. The same thing happens when I run the published executable. The window opens, but the page doesn't load, and the mouse constantly toggles loading icon on/off. Screenshot attached of what loads when running the executable. When I use "framework-dependent" instead of "self-contained", the published executable works perfectly.
I checked out the potential fix you mentioned for self hosting the BrowserSubprocess. I added the following code to my Main method and publishing with self-contained on .NET 5 for WinForms seems to work:
Cef.EnableHighDPISupport(); // added this section below var exitCode = CefSharp.BrowserSubprocess.SelfHost.Main(args); if (exitCode >= 0) { return exitCode;` } var settings = new CefSettings();` settings.BrowserSubprocessPath = System.IO.Path.GetFullPath("{InsertMyExecutableFile.exe}");Reacted by Cong Zhang and ringwaldKThe
BrowserSubprocessis actually anetcoreapp3.1exe with<RollForward>Major</RollForward>specified so it should run with a newer.Net 5runtime installed. In my limited testing this workings when using the installed runtime. I suspect (though haven't done any testing) that it's not working when self contained, possibly the framework version used is trimmed down and missing pieces required for the rollforward.This may actually have nothing to do with it at all. The
CefSharp.BrowserSubprocess.exedistributed with theNugetpackages doesn't want to use the self contained.Net Core/Net 5distribution. As the generatedexeis a native executable it's not really going to be easy to debug the difference.For publishing self contained and single file applications self hosting the
BrowserSubprocessis required.For
WinFormsyourProgram.cswould look something like:[STAThread] public static int Main(string[] args) { //To support High DPI this must be before CefSharp.BrowserSubprocess.SelfHost.Main so the BrowserSubprocess is DPI Aware Cef.EnableHighDPISupport(); var exitCode = CefSharp.BrowserSubprocess.SelfHost.Main(args); if (exitCode >= 0) { return exitCode; } var settings = new CefSettings() { //By default CefSharp will use an in-memory cache, you need to specify a Cache Folder to persist data CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache"), BrowserSubprocessPath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName }; //Perform dependency check to make sure all relevant resources are in our output directory. Cef.Initialize(settings, performDependencyCheck: false, browserProcessHandler: null); var browser = new BrowserForm(); Application.Run(browser); return 0; }
See https://github.com/cefsharp/CefSharp/blob/cefsharp/87/CefSharp.Core/BrowserSubprocess/SelfHost.cs#L26 for additional details.
Target machines still require
VC++ 2019 Runtime. It's likely you can package this as theUniversal CRTis already included (so is a customvcruntime140_cor3.dllfor.Net Core 3.1, not clear which version this is though, or if it's usable.)
For future reference
dotnet/sdk#14488 (comment)
dotnet/runtime#46990
https://github.com/dotnet/cli/blob/master/Documentation/specs/runtime-configuration-file.mdReacted by Dustin Rowland and Uwe KeimReacted by Peter Rekdal Khan-Sunde and Uwe KeimReacted by Uwe KeimFor SelfContained builds deleting the
CefSharp.BrowserSubprocess.runtimeconfig.jsonappears to resolve the issue with theBrowserSubprocessnot starting.MyApp.runtimeconfig.json - An optional configuration file containing runtime configuration settings. This file is required for framework-dependent applications, but not for self-contained apps.
As
CefSharp.BrowserSubprocess.runtimeconfig.jsonis optional when included inself-containedremoving it whenSelfContained = truewould appear to be a reasonable option. Commit a3e8e91 removes the file fromReferenceCopyLocalPaths. TheCefSharp.BrowserSubprocess.exewould appear to default to the included runtime. When running asFramework Dependantthis shouldn't be a problem as the exe should run on.Net Core 3.1and.Net 5.0runtimes.
.Net Core 3.1
- Testing with and both self contained and single file apps appear to be working as expected.
.Net 5.0
- Normal (non publish)
net5.0-windowsbuild withSelfContained = trueworks as expected - When publishing as SelfContained the
CefSharp.BrowserSubprocess.runtimeconfig.jsonfile still included, removing it manually and updating the apps .deps.json works as expected, so it's just a matter of excluding the file from the publish target. - Publishing a
SingleFileapp as bothSelfContained = trueandSelfContained = falsewould appear to work as expected if the.Net Core 3.1 runtimeis installed. Tested withWindows Sandbox(remember to installVC++ 2019runtime for the arch you are targetingx86 or x64)
Removing the file from the
Publishtarget should hopefully resolve this.Important
.Net 5.0behaves differently to.Net Core 3.1in terms of Single File apps see- https://docs.microsoft.com/en-us/dotnet/core/deploying/single-file
- https://docs.microsoft.com/en-us/dotnet/core/deploying/single-file#other-considerations
- https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/design.md#optional-settings
- Native files aren't included by default for Single File, need to set
IncludeNativeLibrariesForSelfExtract=true - To use the included
BrowsersubProcessthe exe needs to extract the program to disk which is no longer the default. Need to setIncludeAllContentForSelfExtract=trueI've not tested a self hostedBrowserSubprocesswith the default in memory behaviour.
Using
88.2.90-RCI3922build with https://github.com/cefsharp/CefSharp.MinimalExample/tree/cefsharp/88 changing the TargetFramework to net5.0-windowsdotnet publish CefSharp.MinimalExample.netcore.sln -f net5.0-windows -r win-x86 -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:IncludeAllContentForSelfExtract=true --self-contained true --verbosity n
Disclaimer
There are potential issues with runtime dependency mismatch as detailed in dotnet/sdk#14488 (comment)- When self hosting the
BrowserSubprocess(using your applications exe) this shouldn't be a problem as they're all the same runtime. - Using the provided
CefSharp.BrowserSubprocess.exemay be problematic withSelfContainedbuilds (.Netruntime included with the application).
Reacted by Cong Zhang- added a commit that references this issue
on Feb 27, 2021 - Publishing a
SingleFileapp as bothSelfContained = trueandSelfContained = falsewould appear to work as expected if the.Net Core 3.1 runtimeis installed. Tested withWindows Sandbox(remember to installVC++ 2019runtime for the arch you are targetingx86 or x64)
This should now work with the SelfContained = true and SingleFile = false with .Net 5.0
SelfContained = true and SingleFile = true under .Net 5.0 the apphost has hostfxr.dll and hostpolicy.dll statically linked into the runtime exe. As the included runtime doesn't include the required dlls to run the
CefSharp.BrowserSubprocessthe files will be removed from the generated executable for this use case. SelfHosting theBrowserSubprocesswill be required.Generating a
net5.0-windowsself hosting theBrowserSubprocessappears to work as expected under theWindows Sandbox(remembering to installVC++ 2019)dotnet publish CefSharp.MinimalExample.WinForms.netcore.csproj -f net5.0-windows -r win-x86 -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:IncludeAllContentForSelfExtract=true --self-contained true --verbosity n
See https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/design.md#host-builds
hostfxr.dll and hostpolicy.dll are statically linked, so they aren't usable for our purposes, in theory you could bundle them yourself yourself.Add the following to your project file (or set via command line when using dotnet publish) to see details of the files that are packed into the single file exe.
<TraceSingleFileBundler>true</TraceSingleFileBundler>The
.Net 5.0SingleFile SelfContained exe doesn't appear to contain theUniversal CRT, I'm assuming it's statically linked into the resulting exe, I've not seen seen any documentation confirming this though, just an assumption, https://devblogs.microsoft.com/cppblog/introducing-the-universal-crt/ suggests it's possible.- Publishing a
- added 4 commits that reference this issue
on Mar 1, 2021 The following should copy the
VC++runtime into the bin/publish folders when run underVisual Studio(won't work from the command line). This should work forSelfContainedandFramework Dependantbuilds. I've not tested though I don't expect this to work forPublishSingleFile.<Import Project="$(DevEnvDir)..\..\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.props"/> <Target Name="IncludeVisualCppInOutFolder" AfterTargets="ResolveReferences"> <PropertyGroup> <_VCRedistLocation>$(DevEnvDir)..\..\VC\Redist\MSVC\$(VCToolsRedistVersion)\$(PlatformTarget)\Microsoft.VC142.CRT</_VCRedistLocation> </PropertyGroup> <Message Importance="high" Text="_VCRedistLocation = $(_VCRedistLocation)" /> <ItemGroup> <ReferenceCopyLocalPaths Include="$(_VCRedistLocation)\**\*" /> </ItemGroup> </Target>
The latest
Redistversion included withVisual Studioshould be used.The CefSharp.MinimalExample has been updated to include an example of self hosting the
BrowserSubprocesswhen publishingPublishSingleFile = true.- For demo purposes new application entry points were added to the
WPF/WinFormsexamples, technically this would only have been required for theWPF Example. The new entry point is only used whenPublishSingleFile = true - Rather than have a lot of
#ifstatements a self containedProgramPublishSingleFile.Mainwas added to bothWPF/WinFormsprojects. This should provide an example you can copy/paste with minimal modification. - Version
88.2.90is required for everything to work properly (now available on Nuget.org see Release Notification - 88.2.x #3389 (comment) for details)
Changes were added in commit cefsharp/CefSharp.MinimalExample@9da6406 which should provide a fairly detailed example for those of you who require one.
Researching/Debugging/Documenting takes a significant amount of my time. If you are using
CefSharpin commercial software please considering supporting me via GitHub Sponsors. I need your support to continue developing/maintaining the project.Reacted by Peter Rekdal Khan-Sunde, Konstantin Preißer, Daniel Baird and 喜洋洋- For demo purposes new application entry points were added to the
@amaitland Thank you for solving this! 😃I have enabled github sponsorship from our company.
I have enabled github sponsorship from our company.
@peters Thank you so much!! Please let me know if you have any problems.
Reacted by Peter Rekdal Khan-Sunde

First of all, thank you for the great effort of enabling .NET core support. I tried updating our kiosk software from
net48tonet5.0-windows. Using the latest pre-release this was quite easy. But when I published the application using a self-contained runtime it would run but was unable to render the web browser control. After a bit of experimenting I noticed that if I copy allCefSharpassets to a separate directory and changedCefSettings.BrowserSubprocessPathproperty toPath.Combine(currentDirectory, "cefsharp", "CefSharp.BrowserSubprocess.exe")and not deleting the aforementioned assets from the publish directory everything works as it should.What version of the product are you using?
What architecture x86 or x64?
On what operating system?
Are you using
WinForms,WPForOffScreen?What steps will reproduce the problem?
git clone https://github.com/cefsharp/CefSharp.MinimalExample.gitCefSharp.MinimalExample.Wpf.csprojtarget framework tonet5.0-windowsCefSharp.Wpf.NETCorepackage reference to88.2.40-precd CefSharp.MinimalExampledotnet publish .\CefSharp.MinimalExample.netcore.sln -c Release --runtime win-x64 --self-contained.\CefSharp.MinimalExample.Wpf\bin.netcore\x64\Release\net5.0-windows\win-x64\publish\CefSharp.MinimalExample.Wpf.netcore.exeWhat is the expected output? What do you see instead?