解决WPF WebBrowser当前页面的脚本错误问题

因为会有用户要求,需要将客户端体积最小化,不能使用新的浏览器控件,只能使用WebBrowser。

而WebBrowser是IE内核的,现在很多js的API已经不能识别了。所以会报脚本错误,类似下面这样

 

解决方法的原理:

WebBrowser内部是一个InternetExplorer实例,对应的是IWebBrowser2实例。

IWebBrowser2提供了一个属性Slient,当这个属性值为true时,会禁用所有的弹窗。

 

实现步骤:

1、在界面放置一个WebBrowser,并增加WebBrowser的Navigated事件处理程序

 1 <Window x:Class="WebBrowserScriptError.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WebBrowserScriptError"
 7         mc:Ignorable="d"
 8         Title="MainWindow" Height="450" Width="800">
 9     <Grid>
10         <WebBrowser Source="https://myfreetime.cn" Navigated="WebBrowser_Navigated"></WebBrowser>
11     </Grid>
12 </Window>

 

 

2、导入COM接口IOleServiceProvider

1 [ComImport, Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
2 public interface IOleServiceProvider
3 {
4   [PreserveSig]
5   int QueryService([In] ref Guid guidService, [In] ref Guid riid, [MarshalAs(UnmanagedType.IDispatch)] out object ppvObject);
6 }

 

3、封装一个函数,用于设置启用/禁用浏览器弹框

 1 public void SetSilent(WebBrowser browser, bool silent)
 2 {
 3     if (browser == null)
 4         throw new ArgumentNullException("browser");
 5 
 6     //获取浏览器实例
 7     IOleServiceProvider sp = browser.Document as IOleServiceProvider;
 8     if (sp != null)
 9     {
10         Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
11         Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E");
12 
13         object webBrowser;
14         sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out webBrowser);
15         if (webBrowser != null)
16         {
17             //设置Silent属性
18             webBrowser.GetType().InvokeMember("Silent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.PutDispProperty, null, webBrowser, new object[] { silent });
19         }
20     }
21 }

 

4、在浏览器的Navigated事件处理程序中禁用弹框

1         private void WebBrowser_Navigated(object sender, NavigationEventArgs e)
2         {
3             SetSilent(sender as WebBrowser, true);
4         }

 

示例代码

 

参考资料:

https://learn.microsoft.com/en-us/dotnet/api/microsoft.uii.csr.browser.web.iwebbrowser2?view=dynamics-usd-3

https://learn.microsoft.com/en-us/dotnet/api/microsoft.uii.csr.browser.web.iwebbrowser2.silent?view=dynamics-usd-3#microsoft-uii-csr-browser-web-iwebbrowser2-silent

https://github.com/vbaderks/msf/blob/main/Undocumented%20Shell%20Interfaces.reg

https://learn.microsoft.com/zh-cn/archive/msdn-technet-forums/8a62fed2-24c8-4765-a6ab-aa245fa7f8d5

 

posted @ 2024-10-17 10:39  zhaotianff  阅读(80)  评论(0编辑  收藏  举报