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

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

作   者:zhaotianff - 赵嘉

原文链接[1]:
https://www.cnblogs.com/zhaotianff/p/18471549

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

WebBrowserIE 内核的,现在很多 jsAPI 已经不能识别了。所以会报脚本错误,类似下面这样

ff20a29687aff1dd4762f33355a2187d.png

解决方法的原理:

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

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

实现步骤:

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

界面代码如下所示:
<Window x:Class="WebBrowserScriptError.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WebBrowserScriptError"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <WebBrowser Source="https://myfreetime.cn" Navigated="WebBrowser_Navigated"></WebBrowser>
    </Grid>
</Window>

2、导入 COM 接口 IOleServiceProvider

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

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

public void SetSilent(WebBrowser browser, bool silent)
{
    if (browser == null)
        throw new ArgumentNullException("browser");

    //获取浏览器实例
    IOleServiceProvider sp = browser.Document as IOleServiceProvider;
    if (sp != null)
    {
        Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
        Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E");

        object webBrowser;
        sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out webBrowser);
        if (webBrowser != null)
        {
            //设置Silent属性
            webBrowser.GetType().InvokeMember("Silent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.PutDispProperty, null, webBrowser, new object[] { silent });
        }
    }
}

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

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

0deaa6b394cd4b4023694414d46e52d2.png

示例代码[2]

https://learn.microsoft.com/en-us/dotnet/api/microsoft.uii.csr.browser.web.iwebbrowser2?view=dynamics-usd-3[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[4]

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

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

参考资料

[1]

原文链接: https://www.cnblogs.com/zhaotianff/p/18471549

[2]

示例代码: https://files-cdn.cnblogs.com/files/zhaotianff/WebBrowserScriptError.zip

[3]

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?view=dynamics-usd-3

[4]

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://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

[5]

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

[6]

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值