2009-08-19 165 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