Как подавить ошибки script при использовании элемента управления WPF WebBrowser?

У меня есть приложение WPF, которое использует элемент управления WPF WebBrowser для отображения интересных веб-страниц нашим разработчикам на экране с плоским экраном (например, лента новостей).

Проблема в том, что я иногда получаю ошибку HTML script, которая вызывает неприятное сообщение об ошибке IE, спрашивающее, хочу ли я "перестать запускать скрипты на этой странице". Есть ли способ подавить эту проверку ошибок?

ПРИМЕЧАНИЕ. Я уже отключил отладку script в настройках IE.

Ответ 1

Проблема здесь в том, что WPF WebBrowser не реализовал это свойство, как в элементе управления 2.0.

Лучше всего использовать WindowsFormsHost в вашем приложении WPF и использовать свойство 2.0 WebBrowser: SuppressScriptErrors. Даже тогда вам понадобится приложение для полного доверия, чтобы сделать это.

Не то, что можно назвать идеальным, но это в значительной степени единственный вариант в настоящее время.

Ответ 2

Вот решение, которое я только что сделал с отражением. Решает проблему:) Я запускаю его в событии Navigated, так как кажется, что объект activeX недоступен до этого момента.

Что он делает, устанавливается свойство .Silent на базовом объекте activeX. Это то же самое, что и свойство .ScriptErrorsSuppressed, эквивалентное формам 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 });
 }

Лучшая версия, которая может быть запущена в любое время, а не после события .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 на wb.Navigated.

Ответ 3

Только что найденный из еще один вопрос, это элегантно и отлично работает.

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

activeX.Silent = true;

Ответ 4

Я хотел добавить это как комментарий к ответу @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 #, но он довольно ясно, что он делает.

Ответ 5

Я также нашел интересный способ отключить ошибки JavaScript. Но вам нужно использовать хотя бы .NET Framework 4.0 из-за использования элегантного динамического типа.

Вам нужно подписаться на событие LoadCompleted элемента WebBrowser:

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

Ответ 6

Проверьте приведенный ниже код для подавления ошибок 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 с хостом winforms.. у вас есть свойство "SuppressScriptErrors", установите его в true

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

Ответ 7

У меня эта проблема в прошлом и, наконец, разрешила ее с помощью инъекции Javascript script, которые подавляют обработку ошибок. Надеюсь, это тоже поможет вам.

Отключить ошибки Javascript в WEbBrowsercontrol

Ответ 8

вы можете использовать этот трюк

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)