温故知新,遇见CefSharp,适用于WPF/WinFroms的Chromium嵌入框架的C#版本,让客户端插上Web的翅膀
什么是Cef
Chromium Embedded Framework (CEF). A simple framework for embedding Chromium-based browsers in other applications.
嵌入式Chromium框架(简称CEF
) ,全称Chromium Embedded Framework
,是一个由Marshall Greenblatt
在2008建立的开源项目,它主要目的是开发一个基于Google Chromium
的Web Browser控件。CEF支持一系列的编程语言和操作系统,并且能很容易地整合到新的或已有的工程中去。
市面上,很多主流的浏览器都是都是以这种嵌入Chromium内核的方式进行研发,包括微软最新的作品Microsoft Edge。
它的设计思想是易用且兼顾性能。CEF基本的框架包含C/C++程序接口,通过本地库的接口来实现,而这个库则会隔离宿主程序和Chromium & Webkit的操作细节。它在浏览器控件和宿主程序之间提供紧密的整合,它支持用户插件、协议、Javascript对象以及Javascript扩展,宿主程序可以随意地控件资源下载,导航,下下文内容和打印等,并且可以跟Google Chrome浏览器一起,支持高性能和Html5技术。
其源码:https://bitbucket.org/chromiumembedded/cef/src/master/
什么是CefSharp
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混合架构的业务场景需求,终端技术目前支持:WinFroms
、WPF
、OffScreen
,.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版,所有的版本都将使用CefSharp
、CefSharp.Core
这两个库。
安装环境
软件环境要求:
关于支持AnyCPU:
最新版本已经支持AnyCPU了,细节参见:https://github.com/cefsharp/CefSharp/issues/1714
官方示例
勤学勤练
如果Visual Studio 2019打不开,需要前往工具
-选项
-环境
-预览功能
中,找到使用.Net SDK预览版
这个选项并且勾选上。
创建解决方案及目录
- 新建名为
HelloCefSharp
的解决方案
dotnet new sln -o HelloCefSharp
- 切换到
HelloCefSharp
目录
cd .\HelloCefSharp\
创建.Net Core的WinFroms项目
- 创建名为
demoForWinFormCore
的WinFroms
项目
dotnet new winforms -o demoForWinFormCore -f net5.0
- 添加
demoForWinFormCore
到解决方案
dotnet sln add .\demoForWinFormCore\demoForWinFormCore.csproj
- 切换到
demoForWinFormCore
目录
cd .\demoForWinFormCore\
- 运行
demoForWinFormCore
项目
dotnet watch run
创建.Net Core的WPF项目
- 创建名为
demoForWpfCore
的WinFroms
项目
dotnet new wpf -o demoForWpfCore
- 添加
demoForWpfCore
到解决方案
dotnet sln add .\demoForWpfCore\demoForWpfCore.csproj
- 切换到
demoForWpfCore
目录
cd .\demoForWpfCore\
- 运行
demoForWpfCore
项目
dotnet watch run
创建.Net Framework的WinFroms项目
- 创建名为
demoForWinFormFrame
的WinFroms
项目
这里需要将框架最低设置为:
.Net Framework 4.5.2
,这是目前CefSharp的WinForms包最低兼容版本。
- 运行
demoForWinFormFrame
项目
创建.Net Framework的Wpf项目
- 创建名为
demoForWpfFrame
的WinFroms
项目
- 运行
demoForWpfFrame
项目
.Net Core的WinFroms项目安装CefSharp包
dotnet add package CefSharp.WinForms.NETCore
运行试试:
dotnet watch run
.Net Core的WPF项目安装CefSharp包
dotnet add package CefSharp.Wpf.NETCore
运行试试:
dotnet watch run
.Net Framework的WinFroms项目安装CefSharp包
在Visual Studio的demoForWinFormFrame
项目上右键管理Nuget程序包
,搜索关键词CefSharp.WinForms
找到对应的包进行安装即可。
安装后新增文件packages.config
运行试试:
.Net Framework的Wpf项目安装CefSharp包
在Visual Studio的demoForWpfFrame
项目上右键管理Nuget程序包
,搜索关键词CefSharp.Wpf
找到对应的包进行安装即可。
安装后新增文件packages.config
运行试试:
Wpf项目添加ChromiumWebBrowser控件
在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. 运行效果
4. .Net Core的Wpf项目同理
WinFroms项目添加ChromiumWebBrowser控件
在demoForWinFormFrame
项目中,双击打开MainForm.cs
,展开窗体设计器。
1. 在Visual Studio的视图菜单中启用工具箱视图。
这样我们便可以在工具箱中看到CefSharp提供的两个浏览器嵌入控件了。
2. 我们选取ChromiumWebBrowser
控件拖入右侧的窗体设计器中,默认他会以填充的形式加入进入,改名控件为Browser
。
3. 接下来我们在MainForm.cs
的Load
事件中加载指定的初始化网址即可。
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. 运行效果
5. 或者在Main2Form.cs
中先拖入一个名为MainPanel
的Panel控件。
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. 运行效果
初始化并配置Cef、浏览器设置
/// <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);
}
var browser = new ChromiumWebBrowser("www.bing.com")
{
BrowserSettings =
{
DefaultEncoding = "UTF-8",
WebGl = CefState.Disabled
}
};
参考
- https://cefsharp.github.io
- Chromium Embedded Framework基本用法及理解
- CefSharp-基于C#的客户端开发框架技术栈开发全记录
- Chromium Embedded Framework
- Chromium Embedded Framework中文文档之(基本使用)
- 浏览器内核版本检测
- iOS 离屏渲染优化(Offscreen Render)
- Android OpenGL ES 离屏渲染(offscreen render)
- https://github.com/microsoft/CsWin32
- https://github.com/cefsharp/CefSharp/wiki/Quick-Start