使用WPF WebBrowser控件时如何禁止脚本错误?

问题描述 投票:46回答:8

我有一个WPF应用程序,它使用WPF WebBrowser控件在平板显示器(如新闻源)上向开发人员显示有趣的网页。

麻烦的是,我偶尔会得到一个HTML脚本错误,弹出一个讨厌的IE错误消息,询问我是否要“停止在此页面上运行脚本”。有没有办法抑制这个错误检查?

注意:我已经在IE设置中禁用了脚本调试。

wpf browser
8个回答
7
投票

这里的问题是WPF WebBrowser没有像2.0控件那样实现这个属性。

你最好的选择是在你的WPF应用程序中使用WindowsFormsHost并使用2.0的WebBrowser属性:SuppressScriptErrors。即使这样,您也需要完全信任该应用程序才能执行此操作。

不是人们所说的理想,但它几乎是目前唯一的选择。


122
投票

这是我刚用反射做出的解决方案。解决问题:)我在Navigated事件中运行它,因为似乎activeX对象在此之前不可用。

它的作用是在底层的activeX对象上设置.Silent属性。这与Windows窗体等效的.ScriptErrorsSuppressed属性相同。

 public void HideScriptErrors(WebBrowser wb, bool Hide) {
    FieldInfo fiComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
    if (fiComWebBrowser == null) return;
    object objComWebBrowser = fiComWebBrowser.GetValue(wb);
    if (objComWebBrowser == null) return;
    objComWebBrowser.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { Hide });
 }

一个更好的版本,可以在任何时候运行,而不是在.Navigated事件之后运行:

public void HideScriptErrors(WebBrowser wb, bool hide) {
    var fiComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
    if (fiComWebBrowser == null) return;
    var objComWebBrowser = fiComWebBrowser.GetValue(wb);
    if (objComWebBrowser == null) {
        wb.Loaded += (o, s) => HideScriptErrors(wb, hide); //In case we are to early
        return;
    }
    objComWebBrowser.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { hide });
}

如果对第二个样本有任何问题,请尝试交换wb.Loaded with wb.Navigated。


9
投票

刚刚从another question找到,这是优雅的,工作得很好。

dynamic activeX = this.webBrowser1.GetType().InvokeMember("ActiveXInstance",
                BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
                null, this.webBrowser1, new object[] { });

activeX.Silent = true;

5
投票

我想将此添加为@Alkampfer答案的评论,但我没有足够的声誉。这适用于我(Windows 8.1,NET 4.5):

 window.Browser.LoadCompleted.Add(fun _ -> 
    window.Browser.Source <- new System.Uri("javascript:window.onerror=function(msg,url,line){return true;};void(0);"))

这段代码示例是用F#编写的,但很清楚它是做什么的。


4
投票

我还发现了一种有趣的方法来禁用JavaScript错误。但由于使用了优雅的动态类型,您至少需要使用.Net Framework 4.0。

您需要订阅WebBrowser元素的LoadCompleted事件:

<WebBrowser x:Name="Browser" 
            LoadCompleted="Browser_OnLoadCompleted" />

之后,您需要编写一个如下所示的事件处理程序:

    void Browser_OnLoadCompleted(object sender, NavigationEventArgs e)
    {
        var browser = sender as WebBrowser;

        if (browser == null || browser.Document == null)
            return;

        dynamic document = browser.Document;

        if (document.readyState != "complete")
            return;

        dynamic script = document.createElement("script");
        script.type = @"text/javascript";
        script.text = @"window.onerror = function(msg,url,line){return true;}";
        document.head.appendChild(script);
    }

3
投票

检查以下代码以禁止WPF浏览器控件的脚本错误。

    public MainWindow
    {
    InitializeComponent();
    WebBrowserControlView.Navigate(new Uri("https://www.hotmail.com"));
                        //The below checks for script errors.
    ViewerWebBrowserControlView.Navigated += ViewerWebBrowserControlView_Navigated;
    }

void ViewerWebBrowserControlView_Navigated(object sender, NavigationEventArgs e)
            {
    BrowserHandler.SetSilent(ViewerWebBrowserControlView, true); // make it silent
            }

public static class BrowserHandler
{
    private const string IWebBrowserAppGUID = "0002DF05-0000-0000-C000-000000000046";
    private const string IWebBrowser2GUID = "D30C1661-CDAF-11d0-8A3E-00C04FC9E26E";

    public static void SetSilent(System.Windows.Controls.WebBrowser browser, bool silent)
    {
        if (browser == null)
            MessageBox.Show("No Internet Connection");

        // get an IWebBrowser2 from the document
        IOleServiceProvider sp = browser.Document as IOleServiceProvider;
        if (sp != null)
        {
            Guid IID_IWebBrowserApp = new Guid(IWebBrowserAppGUID);
            Guid IID_IWebBrowser2 = new Guid(IWebBrowser2GUID);

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

}

[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);


   }

然而,如果您使用Winforms Web浏览器和winforms主机..您有一个属性“SuppressScriptErrors”将其设置为true

    <WindowsFormsHost Name="WinformsHost" Grid.Row="1">
    <winForms:WebBrowser x:Name="WebBrowserControlView" ScriptErrorsSuppressed="True" AllowWebBrowserDrop="False"></winForms:WebBrowser>
</WindowsFormsHost>

2
投票

我在过去遇到过这个问题,最后通过注入一个可以抑制错误处理的Javascript脚本解决了这个问题。希望这也可以帮到你。

Disable Javascript errors in WEbBrowsercontrol


1
投票

你可以使用这个技巧

VB.net

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Private Const WM_CLOSE As Short = &H10s

并调用最后一个lib:

 dim hwnd 
    dim vreturnvalue
    hwnd = FindWindow(vbNullString,"script error")
    if hwnd<>0 then vreturnvalue = SendMessage(hwnd, WM_CLOSE,  &O0s, &O0s)
© www.soinside.com 2019 - 2024. All rights reserved.