使用CefSharp实现C#和Web页面交互
CefSharp是Chromium的.NET版封装,用于在WinForm和WPF中嵌入浏览器功能,并能让C#代码和页面进行交互。
CEF是Chromium Embedded Framework的简称,这个框架专门用于将Chromium嵌入到其他程序中。而CefSharp在这个框架的基础上封装了.NET版,Github开源:https://github.com/cefsharp/CefSharp。
CefSharp支持WinForm和WPF,本文讲解一下在WinForm中C#和页面的交互,官方Wiki有文档,可以加深了解。
首先创建一个WinForm项目,安装NuGet包CefSharp.WinForms,注意安装NuGet需要很长时间,所有依赖大概400M。
在程序启动时需要初始化Cef一次,所以在Program.cs中添加以下代码。
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var setting = new CefSharp.CefSettings();
setting.Locale = "zh-CN";
setting.CachePath = "cache";
CefSharp.Cef.Initialize(setting);
Application.Run(mainForm = new Form1());
CefSharp.Cef.Shutdown();
}
即必须调用Cef.Initialize()
初始化才能使用,程序退出时必须Shutdown,Cef.Shutdown()
方法可以调用多次,务必保证被调用,否则运行几次内存就爆了。
下面来看具体实现代码,后边详细讲解。
using System;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
namespace cef
{
public partial class Form1 : Form
{
private ChromiumWebBrowser browser;
public Form1()
{
InitializeComponent();
//初始化控件并添加到Form
browser = new ChromiumWebBrowser("http://www.abelliu.com");
browser.Dock = DockStyle.Fill;
this.panelBottom.Controls.Add(browser);
browser.FrameLoadEnd += Browser_FrameLoadEnd;
}
private void Form1_Load(object sender, EventArgs e)
{
//注册C#的方法到页面中
var obj = new BoundObject();
browser.RegisterJsObject("bound", obj);
}
//页面加载完注入我们的JS代码
private void Browser_FrameLoadEnd(object sender, CefSharp.FrameLoadEndEventArgs e)
{
if (e.Frame.IsMain)
{
browser.ExecuteScriptAsync(@"
document.body.onmouseup = function() {
bound.onSelected(window.getSelection().toString());
}");
}
}
public void ShowJsResult(string message)
{
this.Invoke(new Action(() => { this.richTextBox1.Text = message; }));
}
}
public class BoundObject
{
public void OnSelected(string selectedText)
{
Program.mainForm.ShowJsResult(selectedText);
}
}
}
我们定义了一个类BoundObject
和一个方法OnSelected()
来实现在JS中调用,类和方法名随意,但是特别注意,方法参数必须用首字母小写的驼峰命名。
Form1_Load中使用browser.RegisterJsObject("bound", obj);
将我们的类封装并在页面的JS引擎中注册,然后Browser_FrameLoadEnd
事件中注入我们需要执行的JS,JS中调用bound.onSelected()
就会调到我们的C#代码。这个bound名随意。注意在JS调用时的名称都是标准的驼峰名字,首字母小写,因为这是JS的标准命名方法,我也是因为调用不成功测试了好久才发现。。
现在运行程序,使用鼠标选择页面中的文字,然后选择的文字会展示在WinForm中。
本文源码在GitHub:https://github.com/Abel-Liu/CefSharpSample