温故知新,遇见CefSharp,适用于WPF/WinFroms的Chromium嵌入框架的C#版本,让客户端插上Web的翅膀

什么是Cef

https://github.com/chromiumembedded/cef

Chromium Embedded Framework (CEF). A simple framework for embedding Chromium-based browsers in other applications.

image

嵌入式Chromium框架(简称CEF) ,全称Chromium Embedded Framework,是一个由Marshall Greenblatt在2008建立的开源项目,它主要目的是开发一个基于Google Chromium的Web Browser控件。CEF支持一系列的编程语言和操作系统,并且能很容易地整合到新的或已有的工程中去。

image

市面上,很多主流的浏览器都是都是以这种嵌入Chromium内核的方式进行研发,包括微软最新的作品Microsoft Edge。

https://www.chromium.org

image

它的设计思想是易用且兼顾性能。CEF基本的框架包含C/C++程序接口,通过本地库的接口来实现,而这个库则会隔离宿主程序和Chromium & Webkit的操作细节。它在浏览器控件和宿主程序之间提供紧密的整合,它支持用户插件、协议、Javascript对象以及Javascript扩展,宿主程序可以随意地控件资源下载,导航,下下文内容和打印等,并且可以跟Google Chrome浏览器一起,支持高性能和Html5技术。

其源码https://bitbucket.org/chromiumembedded/cef/src/master/

什么是CefSharp

https://cefsharp.github.io

CefSharp is a simple .Net wrapper around the Chromium Embedded Framework (CEF). CEF is an open source project based on the Google Chromium project. Unlike the Chromium project itself, which focuses mainly on Google Chrome application development, CEF focuses on facilitating embedded browser use cases in third-party applications. CEF is based on the multi-process Chromium Content API and as a result only a subset of the features that exist in Chromium are currently available. For example, support for extensions is limited, only a subset of the Extension API is implemented.

CefSharp嵌入式Chromium框架(Chromium Embedded Framework)的C#实现版本,让基于.Net的Windows客户端能方便的把Chromium核心嵌入其中,满足Hybrid混合架构的业务场景需求,终端技术目前支持:WinFromsWPFOffScreen,.Net框架不仅支持.Net Framework,还支持最新的.Net Core 3.1 / Net 5

CefSharp provides three different flavors, WinForms, WPF and OffScreen. The WPF and OffScreen versions use the OffScreen Rendering(OSR) rendering mode. In OSR mode each frame is rendered to a buffer and then either drawn on the screen as in the case of WPF or available as a Bitmap in the OffScreen. All versions use the CefSharp and CefSharp.Core libraries, as a result much of the API is used exactly the same within all three flavors. This limits code duplication and reduces the maintenance burden of adding a new feature, the only downside is the WPF version is not quite as WPF friendly as it could be (you can subclass the ChromiumWebBrowser class and implement any missing parts in your application that are required). Also you can host the WinForms version within WPF using the WindowsFormsHost, this may be required to get around some limitations of the WPF version (CEF has yet to implement full touch screen support in the OSR mode, there is an open issue on the CEF Issue Tracker, if this is something you require, get involved there).

Off-Screen Rendering 离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作

CefSharp的WPF和OffScreen版本使用了离屏渲染机制(OffScreen Rendering, OSR),但是在OSR模式下,Cef暂时没有全触屏的接口支持,所以WPF版本还是存在一些限制,如果有必要你可以在WPF中可通过WindowsFormsHost技术来嵌入WinForms版,所有的版本都将使用CefSharpCefSharp.Core这两个库。

image

安装环境

https://github.com/cefsharp/CefSharp/releases

软件环境要求:

关于支持AnyCPU:

最新版本已经支持AnyCPU了,细节参见:https://github.com/cefsharp/CefSharp/issues/1714

官方示例

https://github.com/cefsharp/CefSharp.MinimalExample

勤学勤练

https://github.com/TaylorShi/HelloCefSharp

如果Visual Studio 2019打不开,需要前往工具-选项-环境-预览功能中,找到使用.Net SDK预览版这个选项并且勾选上。

image

创建解决方案及目录

  1. 新建名为HelloCefSharp的解决方案
dotnet new sln -o HelloCefSharp

image

  1. 切换到HelloCefSharp目录
cd .\HelloCefSharp\

image

创建.Net Core的WinFroms项目

  1. 创建名为demoForWinFormCoreWinFroms项目
dotnet new winforms -o demoForWinFormCore -f net5.0

image

  1. 添加demoForWinFormCore到解决方案
dotnet sln add .\demoForWinFormCore\demoForWinFormCore.csproj

image

  1. 切换到demoForWinFormCore目录
cd .\demoForWinFormCore\

image

  1. 运行demoForWinFormCore项目
dotnet watch run

image

创建.Net Core的WPF项目

  1. 创建名为demoForWpfCoreWinFroms项目
dotnet new wpf -o demoForWpfCore

image

  1. 添加demoForWpfCore到解决方案
dotnet sln add .\demoForWpfCore\demoForWpfCore.csproj

image

  1. 切换到demoForWpfCore目录
cd .\demoForWpfCore\

image

  1. 运行demoForWpfCore项目
dotnet watch run

image

创建.Net Framework的WinFroms项目

  1. 创建名为demoForWinFormFrameWinFroms项目

image

这里需要将框架最低设置为:.Net Framework 4.5.2,这是目前CefSharp的WinForms包最低兼容版本。

image

  1. 运行demoForWinFormFrame项目

image

创建.Net Framework的Wpf项目

  1. 创建名为demoForWpfFrameWinFroms项目

image

image

  1. 运行demoForWpfFrame项目

image

.Net Core的WinFroms项目安装CefSharp包

https://www.nuget.org/packages/CefSharp.WinForms.NETCore

dotnet add package CefSharp.WinForms.NETCore

image

image

运行试试:

dotnet watch run

image

.Net Core的WPF项目安装CefSharp包

https://www.nuget.org/packages/CefSharp.Wpf.NETCore

dotnet add package CefSharp.Wpf.NETCore

image

运行试试:

dotnet watch run

image

.Net Framework的WinFroms项目安装CefSharp包

https://www.nuget.org/packages/CefSharp.WinForms

在Visual Studio的demoForWinFormFrame项目上右键管理Nuget程序包,搜索关键词CefSharp.WinForms找到对应的包进行安装即可。

image

安装后新增文件packages.config

image

运行试试:

image

.Net Framework的Wpf项目安装CefSharp包

https://www.nuget.org/packages/CefSharp.Wpf

在Visual Studio的demoForWpfFrame项目上右键管理Nuget程序包,搜索关键词CefSharp.Wpf找到对应的包进行安装即可。

image

安装后新增文件packages.config

image

运行试试:

image

Wpf项目添加ChromiumWebBrowser控件

https://github.com/cefsharp/CefSharp/wiki/Quick-Start

demoForWpfFrame项目的MainWindow.xaml文件中。

1. 新增引用CefSharp.Wpf的命名空间

xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"

2. 添加ChromiumWebBrowser控件即可,其中Address便是启动时加载的网址设定

<Window
    x:Class="demoForWpfFrame.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:demoForWpfFrame"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">

    <Border>
        <wpf:ChromiumWebBrowser x:Name="Browser" Address="www.bing.com" />
    </Border>

</Window>

3. 运行效果

image

4. .Net Core的Wpf项目同理

image

WinFroms项目添加ChromiumWebBrowser控件

https://github.com/cefsharp/CefSharp/wiki/Quick-Start

demoForWinFormFrame项目中,双击打开MainForm.cs,展开窗体设计器。

image

1. 在Visual Studio的视图菜单中启用工具箱视图。

image

这样我们便可以在工具箱中看到CefSharp提供的两个浏览器嵌入控件了。

image

2. 我们选取ChromiumWebBrowser控件拖入右侧的窗体设计器中,默认他会以填充的形式加入进入,改名控件为Browser

image

3. 接下来我们在MainForm.csLoad事件中加载指定的初始化网址即可。

namespace demoForWinFormFrame
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            Load += MainForm_Load;
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            Browser.Load("www.bing.com");
        }
    }
}

4. 运行效果

image

5. 或者在Main2Form.cs中先拖入一个名为MainPanel的Panel控件。

image

6. 然后在Main2Form.cs的Load事件中引入ChromiumWebBrowser控件,并且挂载到MainPanel下面。

namespace demoForWinFormFrame
{
    public partial class Main2Form : Form
    {
        public Main2Form()
        {
            InitializeComponent();
            Load += Main2Form_Load;
        }

        private void Main2Form_Load(object sender, EventArgs e)
        {
            var browser = new ChromiumWebBrowser("www.bing.com");
            MainPanel.Controls.Add(browser);
        }
    }
}

7. 运行效果

image

初始化并配置Cef、浏览器设置

https://github.com/cefsharp/CefSharp.MinimalExample/blob/master/CefSharp.MinimalExample.WinForms/Program.cs

https://github.com/cefsharp/CefSharp/wiki/General-Usage#1-how-do-you-call-a-javascript-method-from-net

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
    InitCef();

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Main2Form());
}
private static void InitCef()
{
    #if ANYCPU
    CefRuntime.SubscribeAnyCpuAssemblyResolver();
    #endif

    //For Windows 7 and above, best to include relevant app.manifest entries as well
    Cef.EnableHighDPISupport();

    var settings = new CefSettings
    {

        // Increase the log severity so CEF outputs detailed information, useful for debugging
        LogSeverity = LogSeverity.Verbose,
        // By default CEF uses an in memory cache, to save cached data e.g. to persist cookies you need to specify a cache path
        // NOTE: The executing user must have sufficient privileges to write to this folder.
        CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache")
    };

    //Example of setting a command line argument
    //Enables WebRTC
    // - CEF Doesn't currently support permissions on a per browser basis see https://bitbucket.org/chromiumembedded/cef/issues/2582/allow-run-time-handling-of-media-access
    // - CEF Doesn't currently support displaying a UI for media access permissions
    //
    //NOTE: WebRTC Device Id's aren't persisted as they are in Chrome see https://bitbucket.org/chromiumembedded/cef/issues/2064/persist-webrtc-deviceids-across-restart
    settings.CefCommandLineArgs.Add("enable-media-stream");
    //https://peter.sh/experiments/chromium-command-line-switches/#use-fake-ui-for-media-stream
    settings.CefCommandLineArgs.Add("use-fake-ui-for-media-stream");
    //For screen sharing add (see https://bitbucket.org/chromiumembedded/cef/issues/2582/allow-run-time-handling-of-media-access#comment-58677180)
    settings.CefCommandLineArgs.Add("enable-usermedia-screen-capturing");

    //Perform dependency check to make sure all relevant resources are in our output directory.
    Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
}

image

var browser = new ChromiumWebBrowser("www.bing.com")
{
    BrowserSettings =
    {
        DefaultEncoding = "UTF-8",
        WebGl = CefState.Disabled
    }
};

参考

posted @ 2021-08-26 23:54  TaylorShi  阅读(6041)  评论(0编辑  收藏  举报