Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional PackageReference Nuget packages #2795

Closed
5 tasks done
amaitland opened this issue May 31, 2019 · 19 comments
Closed
5 tasks done

Additional PackageReference Nuget packages #2795

amaitland opened this issue May 31, 2019 · 19 comments
Assignees

Comments

@amaitland
Copy link
Member

amaitland commented May 31, 2019

New packages will only support the PackageReference format (VS2017/2019 will be required to use them).

  • [ ] Use the newer runtimes\native nuget feature for new cef.redist.win-x64/cef.redist.win-x86
  • Restructure packages to only copy CEF resources using targets file
  • Set minClientVersion to Nuget version supported by both VS2017/2019 (make it impossible for older versions to install the packages)
  • Create CefSharp.WinForms.x86/CefSharp.WinForms.x64
  • Create CefSharp.WPF.x86/CefSharp.WPF.x64
  • Create CefSharp.OffScreen.x86/CefSharp.OffScreen.x64

There won't be AnyCPU support initially, the older packages will need to be used for that.

References

@amaitland amaitland self-assigned this May 31, 2019
@amaitland amaitland changed the title Upgrade Nuget minClientVersion 3.0 Upgrade Nuget minClientVersion 3.5 May 31, 2019
@amaitland amaitland changed the title Upgrade Nuget minClientVersion 3.5 Additional PackageReference Nuget packages Nov 2, 2019
@amaitland amaitland added this to the 79.0.0 milestone Nov 2, 2019
@TonyValenti
Copy link

Just wanted to let everyone know I'm looking forward to .NET Core 3.0 being fully supported!

@matthias-hoste
Copy link

If help is needed with this then I'd gladly help out as I'm really looking forward to this feature

@amaitland
Copy link
Member Author

Pull Requests are welcome, finishing cefsharp/cef-binary#83 is step one.

@amaitland
Copy link
Member Author

When three new individuals/companies signup to GitHub Sponsors then I'll make time to work on the new set of packages.

For a limited time GitHub will match any donated amount, even a $5 per month donation will make a difference. See About the GitHub Sponsors Matching Fund

amaitland added a commit that referenced this issue Jan 30, 2020
**WORK IN PROGRESS**

Unfortunately the new chromiumembeddedframework.redist.win-x86/chromiumembeddedframework.redist.win-x64 packages
aren't usable yet, the files are copied to the relevant natives folder .net core just doesn't load the dlls.
I suspect if we were to p/invoke the dll then it would be loaded correctly, might need to raise this with .Net Core team.
So for now just using the older cef.redist packages, which expose props that can be used in any other package.
the new CefSharp.Common.win packages will copy the files using the .targets file as before, difference being PlatformTarget
is used instead of Platform so we can detect the actual platform of the project not the solution.

AnyCPU is not currently supported, x86/x64 only, Win32 might work, not tested though.
Not clear that AnyCpu will be possible, more digging to do on that front.

Issue #2795
@amaitland
Copy link
Member Author

Thanks to those that have started sponsoring my efforts!

Commit bd9e568 adds what I'd class as an alpha level of quality set of packages.

The packages are on the CefSharp Myget Feed, they'll need testing and bug fixing before they're ready to upload to Nuget.org

CefSharp.Common.win-x64
CefSharp.Common.win-x86
CefSharp.OffScreen.win-x64
CefSharp.OffScreen.win-x86.
CefSharp.WinForms.win-x64
CefSharp.WinForms.win-x86
CefSharp.Wpf.win-x64
CefSharp.Wpf.win-x86

The minClientVersion="4.0.0" will limit these packages to VS2017 and above.

Unfortunately the new chromiumembeddedframework.redist.win-x86/chromiumembeddedframework.redist.win-x64 packages aren't usable yet, the files are copied to the relevant natives .net core folder just doesn't load the dlls. I suspect if we were to p/invoke the dll then it would be loaded correctly, might need to raise this with .Net Core team.

So for now just using the older cef.redist packages, which expose props that can be used in any other package. The new CefSharp.Common.win packages will copy the files using the .targets file as before, difference being PlatformTarget is used instead of Platform so we can detect the actual platform of the project not the solution.

AnyCPU is not currently supported, x86/x64 only, Win32 might work, not tested though.
Not clear that AnyCpu will be possible, more digging to do on that front.

They're not ready yet, progress has been made though.

@amaitland
Copy link
Member Author

I've got a MinimalExample branch for testing purposes, it's yet to be updated to the latest CI build so won't be usable by anyone else yet.

@amaitland
Copy link
Member Author

amaitland commented Feb 1, 2020

https://github.com/cefsharp/CefSharp.MinimalExample/tree/testing/packagereference has been updated to 79.1.360-CI3420, anyone should be able to download and test should they feel so inclined.

@amaitland
Copy link
Member Author

Swiftshader and locales being visible has been moved to dotnet/project-system#5859

@amaitland
Copy link
Member Author

I'll have one more go at seeing if the new packages from cefsharp/cef-binary#83 can be used, see what procmon thinks is actually happening when the assemblies are being resolved.

@amaitland
Copy link
Member Author

Progressing with what we have now seems like the way forward at the moment.

I'll update https://github.com/cefsharp/CefSharp.MinimalExample/tree/testing/packagereference shortly with the latest CI Build.

If anyone is up for Beta Testing the packages please let me know.

@amaitland
Copy link
Member Author

I'll have one more go at seeing if the new packages from cefsharp/cef-binary#83 can be used, see what procmon thinks is actually happening when the assemblies are being resolved.

Additional testing and I still cannot get .Net Core to load libcef.dll automatically, a call to NativeLibrary.TryLoad is required, will move forward instead of waiting to see what happens here.

I'll update https://github.com/cefsharp/CefSharp.MinimalExample/tree/testing/packagereference shortly with the latest CI Build.

The branch has been updated.

@amaitland
Copy link
Member Author

amaitland commented Feb 19, 2020

Remembering there is no AnyCPU support. Unlike the previous pacakges these rely on TargetPlatform so you only need to be targeting x86/x64 at the project level, not the solution level.


Anyone up for testing using their own project can use the packages from https://www.myget.org/gallery/cefsharp

WPF

WinForms

OffScreen


For example of using your own exe to host the BrowserSubProcess (which eliminates the requirement to have .Net 4.5.2 installed).

WPF
Program.netcore.cs

WinForms
Program.netcore.cs

OffScreen
Is crashing on exit so testing will have to wait until that's been resolved.

@kpreisser
Copy link
Contributor

kpreisser commented Feb 27, 2020

Thank you for providing the new <PackageReference> NuGet packages!
I tested CefSharp.WinForms.win-x64/x86 (79.1.360-CI3438) with a .NET Core 3.1 application (netcoreapp3.1) using the declaration from CefSharp.MinimalExample.WinForms.netcore.csproj, with code in the Main() method to run the Subprocess, and it worked without problems.


Regarding using the new packages in .NET Core apps, I once had an idea to add an automatism that would handle the subprocess run logic, in order to simplify using CefSharp with .NET Core. The automatism would inject a new Main method that either runs the subprocess logic, or alternatively searches for the "original" Main method and calls it.

That way, the user would no longer have to edit the Main method (or add one, e.g. for WPF projects where the Main method is normally compiler-generated, or for VB projects that use the application framework where the Main method is also compiler-generated); it would be sufficient to just add the package reference to CefSharp and use the ChromiumWebBrowser control, just like as in .NET Framework projects.
However, I'm not sure if it is suitable to include it in CefSharp, as it looks a bit "hacky", and has a few disadvantages.

You can see the idea with commits kpreisser@1e3c08e and kpreisser@b588469.

Basically, the NuGet package would contain code file (.cs for C# projects, .vb for VB projects, etc.) which contain a Main method that runs the subprocess if needed, or otherwise searches the current Assembly for another method suitable as Main and calls it.

Details:

  • I think the code file is needed as the program's entry point (Main) cannot be in a separate assembly.
  • The code file contains // <auto-generated /> so analyzers or style tools shouldn't complain about it.
  • The methods contain [DebuggerStepThrough] so that when starting debugging with F11, the debugger doesn't step into this added Main method, but steps directly into the original Main method for better UX.
  • When it finds another Main method using reflection, it creates a delegate so that it doesn't need to be called with reflection overhead, as that would e.g. wrap exceptions in TargetInvocationException rather than throwing them directly (where the debugger can break at the original location).

Additionally, it would use a targets file to add <StartupObject>CefSharp.BrowserSubprocess.WinForms.SubprocessStartupHandler</StartupObject> to override the entry point for the assembly.

However, it has a few disadvantages:

  • AFAIK the code files are only added if a package is referenced directly, rather than transitively, so the file cannot be added to a base reference like CefSharp.Common.win-x64; instead it would need to be added to every downstream package like CefSharp.WinForms, CefSharp.WPF etc.
    In that case, the code files for every package would need to use different namespaces, so that when a user is using all of these packages, they don't add the same file multiple times, which would cause an error.
  • I think it's not possible to somehow access original value of <StartupObject> from the .csproj file in the code, which is why it needs to use reflection to find other Main methods. However, if there are multiple methods that are suitable, the user would need to manually annotate the correct one e.g. with an [EntryPoint] attribute.
  • Similarly, when using an obfuscaton tool, it might rename the original Main method since it is no longer the actual entry point, and then the code wouldn't find it, so the user would need to add [Obfuscation] to the Main method (or to the class, e.g. for WPF projects) to prevent renaming. However, that can be a problem e.g. for VB projects using the application framework, as there the whole class with Main is compiler-generated, but I'm not sure if the application framework is still available in .NET Core.
  • Using reflection to iterate all types of the current assembly may add some delay at startup and may cause other assemblies to be loaded.

Thanks!

@amaitland
Copy link
Member Author

using the declaration from CefSharp.MinimalExample.WinForms.netcore.csproj, with code in the Main() method to run the Subprocess, and it worked without problems.

@kpreisser Thanks for taking the time to test 👍

Basically, the NuGet package would contain code file (.cs for C# projects, .vb for VB projects, etc.) which contain a Main method that runs the subprocess if needed, or otherwise searches the current Assembly for another method suitable as Main and calls it.

It's a very clever idea, just seems a little too invasive for my liking. I'd also be concerned how complex this would be to support, there's bound to be some edge cases that we'd miss, at least initially. There's all the new async Main options that would also need to be supported. We'd probably need to make it option.

I had though about shipping a .Net Core subprocess. I'm hoping we can fairly easily adapt the HostWithHostFxr example and create a native exe that loads CefSharp.BrowserSubProcess.Core and executes a specific method. We'd of course need x86 and x64 variants. Having a special Nuget package that's included as a .NETCoreApp3.0 only dependency.

Hopefully this fits in with our current build infrastructure,

amaitland added a commit that referenced this issue Mar 6, 2020
@amaitland
Copy link
Member Author

I've created a new project to host the net core browsersubprocess

https://github.com/cefsharp/CefSharp.BrowserSubProcess.NetCore

Hopefully ready for testing soon.

@amaitland
Copy link
Member Author

Splitting the Browsersubprocess out into it's own package (just for the exe) should allow for inclusion of the correct dependency based on target framework.

@amaitland
Copy link
Member Author

Based on some additional discussion at #2796 (comment) there might be a way forward using runtime.json to select the correct platform.

It looks like we need a ref assembly for each of your x86/x64 dlls, I think we can switch the C# projects to AnyCpu and look at generating a ref assembly only for CefSharp.Core which should simplify things.

Investigating this now.

amaitland added a commit that referenced this issue Aug 14, 2020
Remove the old win-x64/x86 packages as I'll hopefully get this approach working

**Incomplete**

Issue #2795
Issue #3197
@amaitland
Copy link
Member Author

After a massive restructure of the projects (#3319) there are now a set of .Net Core 3.1 packages (these are also usable for .Net 5.0). See #3284 (comment) for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants