2009-08-19 30 views
45

Tôi có một ứng dụng WPF sử dụng điều khiển WPB WebBrowser để hiển thị các trang web thú vị cho các nhà phát triển của chúng tôi trên màn hình phẳng (như một nguồn cấp dữ liệu tin tức).Làm cách nào để ngăn chặn lỗi tập lệnh khi sử dụng điều khiển WPB WebBrowser?

Sự cố là thỉnh thoảng tôi gặp phải lỗi tập lệnh HTML bật lên thông báo lỗi IE khó chịu hỏi xem tôi có muốn "ngừng chạy tập lệnh trên trang này" hay không. Có cách nào để ngăn chặn việc kiểm tra lỗi này không?

LƯU Ý: Tôi đã tắt tính năng gỡ lỗi tập lệnh trong cài đặt IE.

+1

Tuy nhiên, một giải pháp hai dòng là ở đây: http://stackoverflow.com/a/18289217/1768303 – Noseratio

Trả lời

7

Vấn đề ở đây là WPF WebBrowser không triển khai thuộc tính này như trong điều khiển 2.0.

Đặt cược tốt nhất của bạn là sử dụng WindowsFormsHost trong ứng dụng WPF của bạn và sử dụng thuộc tính WebBrowser của 2.0: SuppressScriptErrors. Thậm chí sau đó, bạn sẽ cần các ứng dụng để được tin tưởng đầy đủ để làm điều này.

Không phải cái nào sẽ gọi là lý tưởng, nhưng hiện tại nó là lựa chọn duy nhất.

+0

Bây giờ có một luận cứ hơn cho tôi chống lại điều này winforms-ghét. Chỉ có quá nhiều 'không thể' của – C4u

110

Đây là giải pháp tôi vừa tạo với sự phản chiếu. Giải quyết vấn đề :) Tôi chạy nó tại sự kiện điều hướng, vì có vẻ như đối tượng activeX không có sẵn cho đến lúc đó.

Điều bạn làm là đặt thuộc tính .Silent trên đối tượng activeX bên dưới. Tương tự như thuộc tính .ScriptErrorsSuppressed tương ứng với các biểu mẫu Windows.

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

Một phiên bản tốt hơn mà có thể chạy bất cứ lúc nào và không sau sự kiện .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 }); 
} 

Nếu bất kỳ vấn đề với mẫu thứ hai, hãy thử trao đổi với wb.Loaded wb.Navigated.

+0

+1 Cảm ơn vì điều này - Tôi thực sự không ưa thích việc sử dụng một 'WindowsFormsHost' để có được chức năng này và mã của bạn dường như thực hiện công việc một cách vinh dự. – Sheridan

+0

Bạn làm cách nào để thêm đối tượng này vào đối tượng webbrowser? – MonsterMMORPG

+4

var wb = new WebBrowser(); wb.Navigated + = (a, b) => {HideScriptErrors (wb, true); }; Chỉ cần chạy điều này một lần, nhưng bạn có ý tưởng. Bạn không thể đặt thuộc tính cho đến khi sự kiện Điều hướng đã được kích hoạt. – Wolf5

2

Tôi đã gặp vấn đề này trong quá khứ và cuối cùng đã giải quyết nó bằng cách tiêm một tập lệnh Javascript để ngăn chặn việc xử lý lỗi. Hy vọng điều này có thể giúp bạn quá.

Disable Javascript errors in WEbBrowsercontrol

+0

Điều này không còn hoạt động trên Windows 8.1 với .NET 4.5. –

+0

Thực ra tôi có nó hoạt động với 8.1 và 4.5 trong chương trình sản xuất, nhưng mã này có thể được thay đổi từ ví dụ đó. Nếu bạn quan tâm, tôi có thể thử xác minh mã mới và thực hiện bài đăng cập nhật. – Alkampfer

1

bạn có thể sử dụng thủ thuật này

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 

và gọi lib sau:

dim hwnd 
    dim vreturnvalue 
    hwnd = FindWindow(vbNullString,"script error") 
    if hwnd<>0 then vreturnvalue = SendMessage(hwnd, WM_CLOSE, &O0s, &O0s) 
3

Kiểm tra mã dưới đây để trấn áp lỗi kịch bản điều khiển trình duyệt 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); 


    } 

Trong khi đó, Nếu bạn đang sử dụng trình duyệt Web Winforms với winforms chủ .. bạn có một tài sản "SuppressScriptErrors" thiết lập nó thành true

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

Bạn nên tham khảo ** [bài đăng gốc] (http://stackoverflow.com/a/6198700/1768303) ** khi bạn sao chép mã hiện có. – Noseratio

4

Tôi cũng tìm thấy một cách thú vị để vô hiệu hóa lỗi JavaScript. Nhưng bạn cần sử dụng ít nhất .Net Framework 4.0 vì sử dụng kiểu động thanh lịch.

Bạn cần phải đăng ký vào trường hợp LoadCompleted của phần tử WebBrowser:

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

Sau đó bạn cần phải viết một event handler trông giống như dưới đây:

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

Trong trường hợp của tôi, mã tôi phải sửa là tạo đánh dấu hoàn chỉnh dưới dạng MemoeryStream và chuyển nó tới trình duyệt bằng NavigateToStream. Vì vậy, giải pháp đơn giản là thêm một hàm window.onerror để xử lý âm thầm lỗi. Cảm ơn bạn @Ashot Muradian – pasx

+0

Nó không hoạt động Tôi đã kiểm tra nó với http://www.dolcegabbana.com/ –

5

tôi muốn để thêm video này như một bình luận cho câu trả lời @Alkampfer, nhưng tôi không có đủ danh tiếng. Này làm việc cho tôi (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);")) 

mẫu mã này được viết bằng F #, nhưng nó khá rõ ràng những gì nó làm.

8

Chỉ tìm thấy từ another question, đây là trang nhã và hoạt động tuyệt vời.

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

activeX.Silent = true; 
+1

Tôi đặt điều này dưới sự kiện 'WebBrowser_OnNavigating' và nó hoạt động! +1 –

Các vấn đề liên quan