2009-08-19 94 views
45

我有一个WPF应用程序,它使用WPF WebBrowser控件在平板显示器(如新闻提要)上向我们的开发人员显示有趣的网页。如何在使用WPF WebBrowser控件时抑制脚本错误?

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

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

+1

另一个两行的解决方案是在这里:http://stackoverflow.com/a/18289217/1768303 – Noseratio 2013-11-06 21:15:22

回答

7

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

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

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

+0

现在有我多了一个论点反对这种WinForms的憎恨。有太多的'不可能' – C4u 2016-06-14 19:51:46

110

这是我用反射制作的解决方案。解决问题:) 我在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。

+0

+1感谢这一点 - 我真的不喜欢使用'WindowsFormsHost'来获得这个功能的开销,而且你的代码看起来很光荣。 – Sheridan 2011-09-05 14:57:45

+0

如何将此添加到网页浏览器对象? – MonsterMMORPG 2012-03-16 02:25:14

+4

var wb = new WebBrowser(); wb.Navigated + =(a,b)=> {HideScriptErrors(wb,true); };只需要运行一次,但你明白了。您无法设置属性,直到导航事件被触发。 – Wolf5 2012-04-12 13:14:54

2

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

Disable Javascript errors in WEbBrowsercontrol

+0

这不再适用于使用.NET 4.5的Windows 8.1。 – 2014-08-22 22:30:48

+0

实际上,我在生产程序中使用8.1和4.5,但代码可能会从该示例中更改。如果您有兴趣,我可以尝试验证新代码并更新帖子。 – Alkampfer 2014-08-23 16:03:38

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) 
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与WinForms的主Web浏览器..你有一个属性“SuppressScriptErrors”设置为真

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

当您复制现有代码时,您应该参考** [原始文章](http://stackoverflow.com/a/6198700/1768303)**。 – Noseratio 2013-11-06 21:10:01

4

我也发现了一个有趣的方法来禁用JavaScript错误。但是你至少需要使用.Net Framework 4。0因为使用了优雅的动态类型。

您需要订阅的web浏览器元素的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); 
    } 
+0

在我的情况下,我必须解决的代码是创建完整的标记为MemoeryStream并将其传递给浏览器与NavigateToStream。所以解决方案只是添加一个默默处理错误的window.onerror函数。谢谢@Ashot Muradian – pasx 2016-04-12 21:48:01

+0

它不工作我检查了它与http://www.dolcegabbana.com/ – 2016-07-22 15:36:43

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#,但是,很明显它做什么。

8

刚刚发现从another question,这是优雅和伟大的作品。

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

activeX.Silent = true; 
+1

我把这个'WebBrowser_OnNavigating'事件下,它的工作原理! +1 – 2017-08-17 19:47:47