如何在使用WPF WebBrowser控件时抑制脚本错误?

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

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

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

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

您最好的select是在您的WPF应用程序中使用WindowsFormsHost ,并使用2.0的WebBrowser属性: SuppressScriptErrors 。 即使那样,你也需要申请才能完全信任才能做到这一点。

不是什么人会称之为理想的,但它是目前唯一的select。

这是我用reflection做的一个解决scheme。 解决了这个问题:)我在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.Navigated交换wb.Loaded。

刚从另一个问题find,这是优雅和伟大的作品。

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

我想添加这个作为@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#编写的,但它很清楚它的作用。

我还发现了一个有趣的方法来禁用JavaScript错误。 但是由于使用了优雅的dynamictypes,所以至less需要使用.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); } 

检查下面的代码来抑制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> 

我在过去遇到过这个问题,最后通过注入一个禁止error handling的Javascript脚本来解决这个问题。 希望这可以帮助你。

在WEbBrowsercontrol中禁用Javascript错误

你可以使用这个技巧

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) 

还有另外一个实现不是从Wolf5的一个实现,但是不依赖于一个私有的WebBrowser类字段,可以在这里find: WPF WebBrowser控件 – 如何禁止脚本错误?