WebView2的踩坑记
对于桌面应用,用来显示Web页面的方式有很多种。比如说:WebBrowser、Cef Sharp、NWJS、WebView2等。CEF应该是最常用的一种页面嵌入方案。
微软原来推出过WebView,实在是过于拉跨,于是现在有了WebView2。
WebView2已经在项目上用上了,这里记录下它目前存在的几个坑。
一、Win7系统下,兼容性不够好
-
Win7系统下,不支持背景透明,背景设置透明会抛出异常。(部分win11也会出现)
-
Win7系统下,不支持父级窗口透明,否则会出现页面渲染不出来的问题。
-
反馈页面:ttps://github.com/MicrosoftEdge/WebView2Feedback/issues/2782
二、以管理员权限运行,部分功能受限
-
无法打开上传对话框
-
无法打开保存对话框
取消管理员权限启动即可解决该问题。
三、WebView2的层级问题
WebView2的层级是置顶的,到导致内嵌WebView2只能在最顶层。因为WebView2是以组件的方式嵌在WPF程序中,所以它的渲染层级是置顶的。
四、EnsureCoreWebView2Async 一直处于等待状态。
当WebView2不在视觉树上时,该方法将一直阻塞。WebView2的进程也不会创建出来。该问题可以通过将WebView2加载到视觉树,初始化后再移除。
五、因为ssl证书不可用导致页面无法访问问题
解决方案如下:先注册
CoreWebView2.ServerCertificateErrorDetected += CoreWebView2ServerCertificateErrorDetected;
事件,在事件中,允许访问
private void CoreWebView2_ServerCertificateErrorDetected(object sender, CoreWebView2ServerCertificateErrorDetectedEventArgs e)
{
//此处可以加一些条件判断
e.Action = CoreWebView2ServerCertificateErrorAction.AlwaysAllow;
}
关闭智能拦截器
CoreWebView2Settings.IsReputationCheckingRequired =false;
该属性默认为True,该属性只有高版本(1.0.1414,1.0.1466或以上)才支持!
参见:https://learn.microsoft.com/zh-cn/microsoft-edge/webview2/release-notes?tabs=dotnetcsharp
六、WebView2.Source赋null值将会引发异常
解决该问题,可以给WebView2赋予空页面。
WebView2.Source = new Uri("about:blank");
七、一些奇怪的异常
尝试解决方法:
-
异常来自 HRESULT:0x8007139F Microsoft.Web.WebView2.Core.Raw.ICoreWebView2Controller.MoveFocus(COREWEBVIEW2MOVEFOCUS_REASON reason)
protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (!isCoreWebView2Initialized||!IsDisposed) return IntPtr.Zero; return base.WndProc(hwnd, msg, wParam, lParam, ref handled); }
-
(异常来自 HRESULT:0x8007139F)Microsoft.Web.WebView2.Core.Raw.ICoreWebView2Controller.set_Bounds(tagRECT Bounds)
尝试解决方法:protected override void OnWindowPositionChanged(Rect rcBoundingBox) { try { //如果没有初始化,就不执行操作 // isCoreWebView2Initialized 是表示 EnsureCoreWebView2Async 方法是否已经执行完成 if (!isCoreWebView2Initialized) return; //已经释放了,就不要再执行了 if (!IsDisposed && IsLoaded) { base.OnWindowPositionChanged(rcBoundingBox); } } catch (InvalidCastException ex) { if (ex.HResult == -2147467262) { //do something } } catch (COMException ex2) { if (ex2.HResult == -2147019873) { //do something } } }
3. The WebView control is no longer valid because the browser process crashed.To work around this, please listen for the CoreWebView2.ProcessFailed event to explicitly manage the lifetime of the WebView2 control in the event of a browser failure.https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2.processfailed(异常来自 HRESULT:0x80131509) Microsoft.Web.WebView2.Wpf.WebView2.VerifyBrowserNotCrashed()
目前观察该问题不会有什么影响,WebView可以自行恢复。
4.WebView2.Dispose引发 调用线程无法访问此对象,因为另一个线程拥有该对象。因为WebView内部存在异步调用,要考虑线程的问题。