cefsharp / CefSharp

.NET (WPF and Windows Forms) bindings for the Chromium Embedded Framework
http://cefsharp.github.io/
Other
9.87k stars 2.92k forks source link

Feature Request - Add .Net 5.0 Support #3284

Closed Thawing75 closed 3 years ago

chris-kruining commented 3 years ago

yes please

Haltroy commented 3 years ago

It seems that .Net 5.0 gets its core from .Net Core, meaning that it's not simple to just update like in .Net Framework. .Net Core implementations should be done first in order to support .Net 5.0. Issue #3197 contains the progress on .Net Core implementation. ~Here's the .Net Portability Analyzer results:~ ~REPORT.zip~ I thought this might help but I'm not happy with the results. Felt like a waste of time.

Edit: I didn't noticed that there was a .Net Core version of the solution. Anyways, It was just a waste of time then. Also, report says that it can be used with platform extensions. I guess that "platform extensions" are just WinForms/WPF. Reports also say the Newtonsoft.Json is not compatible with .Net 5 but .Net 5 itself already has a JSON feature.

When I noticed that .Net 5 is out, I tried to insert ChromiumWebBrowser to an .Net 5 WinForms application but it somehow couldn't find CefSharp DLLs that are in the same folder as the executable but I tried with .Net Framework packages. ~But when I added Net Core packages instead (in a new project) 2 errors showed up:~

julesx commented 3 years ago

A big draw of .NET 5 is the single file executable. I am investigating if using Costura + CefSharp is possible, but it's certainly not simple.

amaitland commented 3 years ago

It seems that .Net 5.0 gets its core from .Net Core, meaning that it's not simple to just update like in .Net Framework. .Net Core implementations should be done first in order to support .Net 5.0.

Firstly supporting .Net 5.0 doesn't necessarily mean compiling a .Net 5.0 specific version. As it is my understanding .Net 5.0 is the version after .Net Core 3.1 and is backwards compatible. https://github.com/cefsharp/CefSharp/issues/3197#issuecomment-732809648 suggests testing with .Net 5.0 to this point has been fairly successful, just a few quirks with the packaging.

At this point in time I believe the .Net Core implementation (https://github.com/cefsharp/CefSharp/issues/3197) will be usable by .Net Core 3.1 and .Net 5.0.

Here's the .Net Portability Analyzer results: REPORT.zip I thought this might help but I'm not happy with the results. Felt like a waste of time.

Thanks, not actually necessary. The CI builds have been successfully compiling a .Net Core version for a few months now. There's a CefSharp3.netcore.sln solution in the project source. The problem is actually creating a set of Nuget packages, progress been slow(I've spent countless hours on this already), there's very little in the way of official guidance from MS in regards to our specific use case.

A big draw of .NET 5 is the single file executable. I am investigating if using Costura + CefSharp is possible, but it's certainly not simple.

@julesx What do you mean by this exactly? Far as I know .Net 5.0 still supports publishing to a single file. Can you provide a reference article?


As it stands the .Net 4.5.2 packages are probably usable with .Net 5.0, a quick test suggests that it is. Follow the instructions at https://github.com/cefsharp/CefSharp.MinimalExample#net-core-support and use

https://github.com/cefsharp/CefSharp.MinimalExample has a set of .Net Core projects, change the TargetFramework to the following and it should work as expected.

<TargetFramework>net5.0-windows</TargetFramework>

This is obviously a stop gap measure. This should be resolved by #3197

amaitland commented 3 years ago

For anyone wishing to try out the Net Core packages there are builds available at

At this point in time you need to set a RuntimeIdentifier. See https://github.com/cefsharp/CefSharp/issues/3197#issuecomment-723378736 for details.


I am looking for suggestions on package naming, the NetCore suffix makes it sounds like they are .Net Core specific. It's not possible to include the dlls in the existing packages, a set with a distinct name is required. If anyone has suggestions e.g. CefSharp.WinForms.NetCore should be CefSharp.WinForms.NetNext (We're definitely not using NetNext) then please let me know.

chris-kruining commented 3 years ago

A big draw of .NET 5 is the single file executable. I am investigating if using Costura + CefSharp is possible, but it's certainly not simple.

Unless I'm an idiot and missed something. I've been working with .net5 for a couple of months now, and the single file executable is only used if you configure your project that way. it isn't even the default

kpreisser commented 3 years ago

Firstly supporting .Net 5.0 doesn't necessarily mean compiling a .Net 5.0 specific version. As it is my understanding .Net 5.0 is the version after .Net Core 3.1 and is backwards compatible. #3197 (comment) suggests testing with .Net 5.0 to this point has been fairly successful, just a few quirks with the packaging.

Agreed, packages built for .NET Core 3.1 should mostly work in .NET 5.0 applications as technically .NET 5.0 is the next version after .NET Core 3.1 (just the naming was changed), so the CefSharp.NETCore packages (once they are finished) should work with .NET 5.0 apps.

(Regarding the single-file executable feature, I think the mechanism has changed in .NET 5.0 compared to .NET Core 3.x, but I haven't look at this in more details to see whether this will still work with the current CefSharp.NETCore packages when you want to create a single-file application.)

An advantage of compiling specifically for .NET 5.0 would be the Windows ARM64 support (once support for the desktop components is provided in a servicing release) (#2944). Unfortunatly, when I tried to switch the TargetFramework of the CefSharp.xxx.netcore projects from netcoreapp3.1 to net5.0, the C++/CLI projects (CefSharp.Core) fail to compile with errors like this (not sure what they mean exactly):

2>MSVCMRTD_netcore.LIB(mstartup.obj) : error LNK2022: metadata operation failed (80131195) :
2>MSVCMRTD_netcore.LIB(mstartup.obj) : error LNK2022: metadata operation failed (80131195) :
2>MSVCMRTD_netcore.LIB(mstartup.obj) : error LNK2022: metadata operation failed (80131195) :
2>LINK : fatal error LNK1255: link failed because of metadata errors

However, when I tried to create an empty C++/CLI project for .NET Core 3.1 and added a ARM64 platform configuration, it seemed to work, producing both the <Project>.dll and the Ijwhost.dll files that are marked as ARM64 files in the PE header. So maybe Windows ARM64 support can still be added even when compiling for netcoreapp3.1 (but will only be usable in .NET 5.0 and higher applications).

amaitland commented 3 years ago

An advantage of compiling specifically for .NET 5.0 would be the Windows ARM64 support

I hadn't actually looked into the specifics of targeting ARM64 as there aren't any builds of CEF available yet. Perhaps consideration to skipping .Net Core 3.1 and targeting .Net 5.0 as the minimum is worth considering.

Unfortunatly, when I tried to switch the TargetFramework of the CefSharp.xxx.netcore projects from netcoreapp3.1 to net5.0, the C++/CLI projects (CefSharp.Core) fail to compile with errors like this (not sure what they mean exactly):

The name MSVCMRTD_netcore.LIB suggests it's a netcore specific lib, I wondering if there's some missing pieces in the .Net 5.0 tooling in regards to Mixed Mode CLI/C++.

Haltroy commented 3 years ago

I tried .Net 5 on CefSharp.Example.WinForms (by just changing CefSharp.Example.WinForms target to .Net 5.0, rest is untouched) and it kinda works. It always gives Access Violation errors when navigating back/forward or refreshing page. Also, application shuts down itself in JS Binding Stress Test (same reason). It even happens when target is .Net Core 3.1. Still don't know what example extension & flie load does but other than that, it works. Details on that AccessViolationException: CefBrowserWrapper.cpp at lines 42-46 accessvex

amaitland commented 3 years ago

It always gives Access Violation errors when navigating back/forward or refreshing page

This is an upstream bug and unrelated to the .Net version. https://bitbucket.org/chromiumembedded/cef/issues/3052/cefclient-crash-reloading-when-you-use-the commit https://github.com/cefsharp/CefSharp/commit/a84d6e09589d9574f26c6dc1a6e755546e3e4be4 upgrades to a newer version which includes the reported fix.

Haltroy commented 3 years ago

It always gives Access Violation errors when navigating back/forward or refreshing page

This is an upstream bug and unrelated to the .Net version. https://bitbucket.org/chromiumembedded/cef/issues/3052/cefclient-crash-reloading-when-you-use-the commit a84d6e0 upgrades to a newer version which includes the reported fix.

Fetched it. Now it works.

amaitland commented 3 years ago

The first set of -pre release packages is now on Nuget.org

The https://github.com/cefsharp/CefSharp.MinimalExample/tree/cefsharp/87 branch of the MinimalExample can be used for testing purposes.

They should work for both .Net Core and .Net 5.0. In a version of two I'll change the main CefSharp.WinForms/Wpf/OffScreen packages to be just meta packages and create a set of Net452 packages, so Nuget will choose the correct package based on framework.

I strongly suggest setting a RuntimeIdentifier. I've done my best to make it work when no RuntimeIdentifier is specified, there are probably use cases when you will need to specify one for it to work.

Specify a RuntimeIdentifier. Use one of the following in your proj file.

<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

Without a RuntimeIdentifier the required files will hopefully be copied to the output folder, as I said there are likely cases where it won't work. For Debug builds I've been setting SelfContained to false (whole .Net Core framework is copied otherwise).

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
    <!--
    When SelfCOntained the whole Runtime is copied, for dev purposes
    We don't need this in our debug builds
    -->
    <SelfContained>false</SelfContained>
</PropertyGroup>

If your proj file specifies multiple platforms e.g. <Platforms>x86;x64</Platforms> then I'd suggest using the following:

<PropertyGroup Condition="'$(PlatformTarget)' == 'x86'">
  <RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>

<PropertyGroup Condition="'$(PlatformTarget)' == 'x64'">
  <RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
  <!--
  When SelfCOntained the whole Runtime is copied, for dev purposes
  We don't need this in our debug builds
  -->
  <SelfContained>false</SelfContained>
</PropertyGroup>

For those migrating from the older packages please remove the entries you added to your proj files.

If you were using WPF it would look like the following:

<!-- Add the following to your csproj/vbproj file -->
<ItemGroup>
  <Reference Update="CefSharp">
      <Private>true</Private>
  </Reference>
  <Reference Update="CefSharp.Core">
      <Private>true</Private>
  </Reference>
  <Reference Update="CefSharp.Wpf">
      <Private>true</Private>
  </Reference>
</ItemGroup>

Make sure this is removed after migrating to the NETCore packages.

amaitland commented 3 years ago

It is recommended that you set a RuntimeIdentifier during development. I've done my best to make it work when no RuntimeIdentifier is specified, there are use cases when you will need to specify one for it to work.

Specify a RuntimeIdentifier. Use one of the following in your proj file.

<RuntimeIdentifier Condition="'$(RuntimeIdentifier)' == ''">win-x86</RuntimeIdentifier>
<RuntimeIdentifier Condition="'$(RuntimeIdentifier)' == ''">win-x64</RuntimeIdentifier>

<!--
You should also set
SelfContained = false (otherwise the whole .Net Framework will be included in your bin folder
-->
<SelfContained Condition="'$(SelfContained)' == ''">false</SelfContained>

Without a RuntimeIdentifier the required files will hopefully be copied to the output folder, as I said there are likely cases where it won't work.

If your proj file specifies multiple platforms e.g. <Platforms>x86;x64</Platforms> then I'd suggest using the following:

<PropertyGroup Condition="'$(PlatformTarget)' == 'x86'">
  <RuntimeIdentifier Condition="'$(RuntimeIdentifier)' == ''">win-x86</RuntimeIdentifier>
  <SelfContained Condition="'$(SelfContained)' == ''">false</SelfContained>
</PropertyGroup>

<PropertyGroup Condition="'$(PlatformTarget)' == 'x64'">
  <RuntimeIdentifier Condition="'$(RuntimeIdentifier)' == ''">win-x64</RuntimeIdentifier>
  <SelfContained Condition="'$(SelfContained)' == ''">false</SelfContained>
</PropertyGroup>

SelfPublish and SelfContained

You will need to self host the BrowserSubProcess using your main application executable. See https://github.com/cefsharp/CefSharp/issues/3407 for details


Known Issues


For those migrating from the older packages to the new NETCore packages then please remove the entries you added to your proj files.

If you were using WPF it would look like the following:

<!-- Add the following to your csproj/vbproj file -->
<ItemGroup>
  <Reference Update="CefSharp">
      <Private>true</Private>
  </Reference>
  <Reference Update="CefSharp.Core">
      <Private>true</Private>
  </Reference>
  <Reference Update="CefSharp.Wpf">
      <Private>true</Private>
  </Reference>
</ItemGroup>

Make sure this is removed after migrating to the NETCore packages.

pmuessig commented 3 years ago

I am having issues getting the WPF MinimalExample working when specifying the RuntimeIdentifier

When I alter the the csproj to add the <RuntimeIdentifier>win-x64</RuntimeIdentifier> it changes the directory structure around and I think paths get mushed together.

Here is how it looks w/o the runtime identifier (no changes): image

And here's the output with an included RuntimeIdentifier: image

The app runs, but the example url doesn't load. The output log contains the following info:

[0224/233859.039:WARNING:gpu_process_host.cc(1266)] The GPU process has crashed 1 time(s)
[0224/233859.131:WARNING:gpu_process_host.cc(1266)] The GPU process has crashed 2 time(s)
[0224/233859.215:WARNING:gpu_process_host.cc(1266)] The GPU process has crashed 3 time(s)
[0224/233859.302:WARNING:gpu_process_host.cc(1266)] The GPU process has crashed 4 time(s)
[0224/233859.399:WARNING:gpu_process_host.cc(1266)] The GPU process has crashed 5 time(s)
[0224/233859.488:ERROR:network_service_instance_impl.cc(286)] Network service crashed, restarting service.
[0224/233859.489:WARNING:gpu_process_host.cc(1266)] The GPU process has crashed 6 time(s)
[0224/233859.489:ERROR:browser_gpu_channel_host_factory.cc(168)] Failed to launch GPU process.
[0224/233859.581:ERROR:network_service_instance_impl.cc(286)] Network service crashed, restarting service.
[0224/233859.632:ERROR:browser_gpu_channel_host_factory.cc(168)] Failed to launch GPU process.
[0224/233859.708:ERROR:network_service_instance_impl.cc(286)] Network service crashed, restarting service.
[0224/233859.809:ERROR:network_service_instance_impl.cc(286)] Network service crashed, restarting service.
[0224/233859.891:ERROR:network_service_instance_impl.cc(286)] Network service crashed, restarting service.
[0224/233859.973:ERROR:network_service_instance_impl.cc(286)] Network service crashed, restarting service.
[0224/233900.056:ERROR:network_service_instance_impl.cc(286)] Network service crashed, restarting service.

was there some additional config in the csproj I missed to get it to work with a specified RID?

amaitland commented 3 years ago

@pmuessig Try setting SelfContained to false, see https://github.com/cefsharp/CefSharp/issues/3284#issuecomment-772132523 for an example.

There appears to be a change in the latest .Net 5.0 SDK that stops the Browsersubprocess from launching.

Anyone wishing to publish a self contained or single file app will need to self host the Browsersubprocess see https://github.com/cefsharp/CefSharp/issues/3407 for details.

pmuessig commented 3 years ago

Thanks for replying so quickly!

I def plan on publishing self contained. Not sure if it matters for this scenario but I plan on also publishing as netcoreapp3.1 - which exhibits the same behavior. I will look into hosting my own browser subprocess and see where that gets me. Thanks!

On Thu, Feb 25, 2021, 12:04 AM Alex Maitland notifications@github.com wrote:

@pmuessig https://github.com/pmuessig Try setting SelfContained to false, see #3284 (comment) https://github.com/cefsharp/CefSharp/issues/3284#issuecomment-772132523 for an example.

There appears to be a change in the latest .Net 5.0 SDK that stops the Browsersubprocess from launching.

Anyone wishing to publish a self contained or single file app will need to self host the Browsersubprocess see #3407 https://github.com/cefsharp/CefSharp/issues/3407 for details.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/cefsharp/CefSharp/issues/3284#issuecomment-785614328, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADI7VOFMRPTRPHBPGBLPH3TAXK4ZANCNFSM4TXXSFWQ .

amaitland commented 3 years ago

For those attempting to load CefSharp.Core.Runtime.dll which results in a BadImageFormatException, it's important to be aware that the .Net Core 3.1/.Net 5.0 runtimes will throw this exception for any form of failure. The exception is often misleading.

Our diagnostics for mixed-mode assembly loading need a bit of work since they throw a BadImageFormatException for basically every failure.

As per https://github.com/dotnet/runtime/issues/31743#issuecomment-582168696 the BadImageFormatException is thrown for any sort of failure, some of the common causes are:

pongba commented 2 years ago

Unfortunatly, when I tried to switch the TargetFramework of the CefSharp.xxx.netcore projects from netcoreapp3.1 to net5.0, the C++/CLI projects (CefSharp.Core) fail to compile with errors like this (not sure what they mean exactly):

2>MSVCMRTD_netcore.LIB(mstartup.obj) : error LNK2022: metadata operation failed (80131195) :
2>MSVCMRTD_netcore.LIB(mstartup.obj) : error LNK2022: metadata operation failed (80131195) :
2>MSVCMRTD_netcore.LIB(mstartup.obj) : error LNK2022: metadata operation failed (80131195) :
2>LINK : fatal error LNK1255: link failed because of metadata errors

I met the same link error when compiling my C++/CLI project targeting .NET 5.0. Did you eventually resolve the issue? If so how?

kpreisser commented 2 years ago

Hi, sorry for not replying earlier.

I met the same link error when compiling my C++/CLI project targeting .NET 5.0. Did you eventually resolve the issue? If so how?

I did not resolve the issue, but it seems that the error might have been resolved at least in the current Visual Studio 2022 version (17.3.3). When I change the TargetFramework of CefSharp.Core.Runtime.netcore (C++/CLI project) to net5.0 and switch the architecture configuration to arm64, the project now builds successfully, whereas for netcoreapp3.1 (that is currently used and buils successfully with VS 2019), I now get an error like this:

2>   Creating library bin.netcore\arm64\Debug\CefSharp.Core.Runtime.lib and object bin.netcore\arm64\Debug\CefSharp.Core.Runtime.exp
2>LINK : error LNK2001: unresolved external symbol _CorDllMain
2>C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Host.win-x64\3.1.28\runtimes\win-x64\native\IJWHOST.lib : warning LNK4272: library machine type 'x64' conflicts with target machine type 'ARM64'
2>bin.netcore\arm64\Debug\CefSharp.Core.Runtime.dll : fatal error LNK1120: 1 unresolved externals
2>Done building project "CefSharp.Core.Runtime.netcore.vcxproj" -- FAILED.

So it seems that once we want to switch AppVeyor to use the Visual Studio 2022 image (e.g. for #4155), it would be required to conditionally set the TargetFramework of the C++/CLI projects for .NET Core (CefSharp.Runtime.Core.netcore, CefSharp.BrowserSubprocess.Core.netcore) to net5.0 when the PlatformTarget is arm64, and set it to netcoreapp3.1 for the other architecturs.