创建WPF项目
安装WbeView2 Nuget包
在窗体中添加命名空间
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
使用控件
<wv2:WebView2 x:Name="webview"/>
在MainWindow中初始化
public MainWindow(){InitializeComponent();this.Closing += MainWindow_Closing;InitializeAsync();webView.NavigationStarting += WebView_NavigationStarting;}private void WebView_NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e){//声明一个对象,暴露给js使用var frame = new Frame();webView.CoreWebView2.AddHostObjectToScript("frame", frame);}async void InitializeAsync(){//显示初始化CoreWebView2await webView.EnsureCoreWebView2Async();打开开发工具//webView.CoreWebView2.OpenDevToolsWindow();//虚拟映射webView.CoreWebView2.SetVirtualHostNameToFolderMapping("html.sample", "./dist", CoreWebView2HostResourceAccessKind.Deny);//导航webView.CoreWebView2.Navigate("https://html.sample/index.html");}private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e){webView.Dispose();}
Frame的实现为:
/// <summary>/// 提供给web页面的api/// </summary>[System.Runtime.InteropServices.ComVisible(true)]//必须加,不然AddHostObjectToScript报异常public class Frame{public void Show(){MessageBox.Show("hello React Native");}/** How to use of Javascript?var win = (window as any).chrome.webview.hostObjects.frame;//get native objectconst sub = async (a: any, b: any) => { return await win.Add(a, b) };//return Promise objectsub(10,2).then((res)=>alert(res));* */public int Add(int a, int b){return a + b;}}
主程序与页面之间的通讯
相较于上述所提的通过JS实现WebView2宿主程序和前端页面进行通信的方法,在WebView2中,更加通用而高效的方式是WebMessage
,它是一个异步的消息通信,并且支持双向通信。
- WebView2 控件中的 Web 内容可以使用
window.chrome.webview.postMessage
向宿主程序发布消息。宿主程序使用任何注册到WebMessageReceived
委托方法处理消息。 - 主程序使用
CoreWebView2.PostWebMessageAsString
或CoreWebView2.PostWebMessageAsJSON
将消息发布到 WebView2 控件中的 Web 内容。这些消息由添加到window.chrome.webview.addEventListener
的处理程序捕获。
前端页面发送消息给宿主程序:
在WebView中定义接收到消息的处理函数:
webView.WebMessageReceived += (s, e) =>
{MessageBox.Show(e.WebMessageAsJson);
};
在前端脚本中发送消息:
(windows as any).chrome.webview.postMessage('hello world');
主程序发消息给前端页面:
在前端脚本中需注册消息的处理函数:
(windows as any).chrome.webview.addEventListener('message', event => alert(event.data));
在主程序有两个方法可以进行发送,分别是PostWebMessageAsJson()
与PostWebMessageAsString()
webView.CoreWebView2.PostWebMessageAsString("hello world");
禁用WebMessage:
如果为了安全起见,也可以通过设置将其禁用:
webView.CoreWebView2.Settings.IsWebMessageEnabled = false;
在这里我们可以实现页面加载完成之后的回调操作
window.onload = function () {(windows as any).chrome.webview.postMessage("chaet page loaded complete!");
};
//接收注册消息
webView.WebMessageReceived += WebLoaded;public void WebLoaded(object? obj, CoreWebView2WebMessageReceivedEventArgs e)
{MessageBox.Show(e.WebMessageAsJson);
}
Dev Protocol
- 使用websocket的方式来驱动
var env = await CoreWebView2Environment.CreateAsync(options:new CoreWebView2EnvironmentOptions("--remote-debugging-port=9222"));
await webView.EnsureCoreWebView2Async(env);
- 使用CoreWebView2内置方法
- 执行命令:
CoreWebView2.CallDevToolsProtocolMethodAsync
- 注册回调:
CoreWebView2.GetDevToolsProtocolEventReceiver
- 执行命令:
await webView.CoreWebView2.CallDevToolsProtocolMethodAsync("Network.enable", "{}");
var eventRecieiver = webView.CoreWebView2.GetDevToolsProtocolEventReceiver("Network.requestWillBeSent");
eventRecieiver.DevToolsProtocolEventReceived += (s, e) =>
{Console.WriteLine(e.ParameterObjectAsJson + "\n");
};
关于CallDevToolsProtocolMethodAsync (string methodName, string parametersAsJson)
方法方法描述:
methodName:The full name of the method in the format
{domain}.{method}
parametersAsJson:A JSON formatted string containing the parameters for the corresponding method.
💡 chromedevtools的操作命名空间与相关方法文档:domain