Wyłącz błąd JavaScript w formancie WebBrowser

105

Tworzę aplikację systemu Windows z kontrolką WebBrowser, która nawiguje do witryny programu SharePoint.
Mój problem polega na tym, że otrzymuję błąd JavaScript.

Jak mogę wyłączyć błąd JavaScript? Nie chcę, żeby się pojawiały.

Dureń
źródło
Ten uratował mi dzień. Naprawdę ...
NANDAKUMAR

Odpowiedzi:

219
webBrowser.ScriptErrorsSuppressed = true;
Matt Jacobsen
źródło
2
Dzięki kolego, zaoszczędziłem dużo czasu!
TheGateKeeper
7
Dla przypomnienia, pod maską ta właściwość robi this.AxIWebBrowser2.Silent = true;
redcalx
12
Powinien był również dodać, że this.AxIWebBrowser2.Silent = true blokuje wszystkie wyskakujące okienka, a nie tylko błędy skryptów, stąd nazwa WebBrowser.ScriptErrorsSuppressd wydaje się być niewłaściwa.
redcalx
1
Czy ktoś może mi powiedzieć, gdzie powinienem napisać tę linię w kodzie? Prosimy o pomoc!!
Har devgun
1
spowoduje to usunięcie wszystkich wyskakujących okienek, w tym pól logowania. Najlepiej użyć tego, co zrobił
redclax
53

Spowoduje to wyłączenie błędów skryptu, a także wyłączenie innych okien, takich jak okno logowania NTLM lub okno akceptacji certyfikatu klienta. Poniższe pomija tylko błędy javascript.

// Hides script errors without hiding other dialog boxes.
private void SuppressScriptErrorsOnly(WebBrowser browser)
{
    // Ensure that ScriptErrorsSuppressed is set to false.
    browser.ScriptErrorsSuppressed = false;

    // Handle DocumentCompleted to gain access to the Document object.
    browser.DocumentCompleted +=
        new WebBrowserDocumentCompletedEventHandler(
            browser_DocumentCompleted);
}

private void browser_DocumentCompleted(object sender, 
    WebBrowserDocumentCompletedEventArgs e)
{
    ((WebBrowser)sender).Document.Window.Error += 
        new HtmlElementErrorEventHandler(Window_Error);
}

private void Window_Error(object sender, 
    HtmlElementErrorEventArgs e)
{
    // Ignore the error and suppress the error dialog box. 
    e.Handled = true;
}
Jamiegs
źródło
To powinno mieć więcej pozytywnych głosów, zdecydowanie właściwy sposób, aby to zrobić. Bonus za możliwość rejestrowania błędów lub wyświetlania własnego powiadomienia, zamiast nigdy nie wiedzieć, że kiedykolwiek się zdarzyły (np. W przypadku aplikacji kiosku).
Mike Marynowski
4
Podczas moich testów odkryłem, że przed uruchomieniem zdarzenia DocumentCompleted pojawiają się okna dialogowe błędów skryptu. Jeśli jednak procedura obsługi WebBrowser.Document.Window.Error jest dołączona jako odpowiedź na zdarzenia Navigated i FileDownloaded, można pominąć większość, jeśli nie wszystkie, okna dialogowe błędów skryptu. (FileDownloaded obsługuje większość scenariuszy, z wyjątkiem na przykład WebBrowser.GoBack, który jest obsługiwany przez Navigated. Samo nawigowanie nie powodowałoby odświeżania strony).
Ej.
@Ej. Świetnie, miałem problemy, w których nie wszystkie błędy JavaScript zostały wychwycone i to prawdopodobnie rozwiązałoby problem, czy przypadkiem miałbyś przykład, jak to zaimplementowałeś.?
Jamiegs
5
Oto, czego użyłem: pastebin.com/UThKifw8 Chociaż musieliśmy także skłonić użytkownika do aktualizacji do IE8, zanim okna dialogowe całkowicie zniknęły.
Ej.
FYI Nie mogłem użyć tego rozwiązania, ponieważ strony HTML zawierały zestawy ramek i ramki, co spowodowało, że kontrole bezpieczeństwa między
ramkami zgłosiły
13

Żadne z powyższych rozwiązań nie było odpowiednie dla mojego scenariusza, obsługa zdarzeń .Navigated i .FileDownload wydawała się być dobrym dopasowaniem, ale dostęp do właściwości WebBrowser.Document wyrzucił wyjątek UnauthorizedAccessException, który jest spowodowany zabezpieczeniami skryptów międzyramkowych (nasza zawartość internetowa zawiera ramki - wszystko włączone ta sama domena / adres, ale ramki mają własne luki w zabezpieczeniach, które są blokowane).

Rozwiązaniem, które działało, było przesłonięcie IOleCommandTarget i przechwycenie poleceń błędów skryptu na tym poziomie. Oto podklasa WebBrowser umożliwiająca osiągnięcie tego:

/// <summary>
/// Subclassed WebBrowser that suppresses error pop-ups.
/// 
/// Notes.
/// ScriptErrorsSuppressed property is not used because this actually suppresses *all* pop-ups.
/// 
/// More info at:
/// http://stackoverflow.com/questions/2476360/disable-javascript-error-in-webbrowser-control
/// </summary>
public class WebBrowserEx : WebBrowser
{
    #region Constructor

    /// <summary>
    /// Default constructor.
    /// Initialise browser control and attach customer event handlers.
    /// </summary>
    public WebBrowserEx()
    {
        this.ScriptErrorsSuppressed = false;
    }

    #endregion

    #region Overrides

    /// <summary>
    /// Override to allow custom script error handling.
    /// </summary>
    /// <returns></returns>
    protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
    {
        return new WebBrowserSiteEx(this);
    }

    #endregion

    #region Inner Class [WebBrowserSiteEx]

    /// <summary>
    /// Sub-class to allow custom script error handling.
    /// </summary>
    protected class WebBrowserSiteEx : WebBrowserSite, NativeMethods.IOleCommandTarget
    {
        /// <summary>
        /// Default constructor.
        /// </summary>
        public WebBrowserSiteEx(WebBrowserEx webBrowser) : base (webBrowser)
        {   
        }

        /// <summary>Queries the object for the status of one or more commands generated by user interface events.</summary>
        /// <param name="pguidCmdGroup">The GUID of the command group.</param>
        /// <param name="cCmds">The number of commands in <paramref name="prgCmds" />.</param>
        /// <param name="prgCmds">An array of OLECMD structures that indicate the commands for which the caller needs status information. This method fills the <paramref name="cmdf" /> member of each structure with values taken from the OLECMDF enumeration.</param>
        /// <param name="pCmdText">An OLECMDTEXT structure in which to return name and/or status information of a single command. This parameter can be null to indicate that the caller does not need this information.</param>
        /// <returns>This method returns S_OK on success. Other possible return values include the following.
        /// E_FAIL The operation failed.
        /// E_UNEXPECTED An unexpected error has occurred.
        /// E_POINTER The <paramref name="prgCmds" /> argument is null.
        /// OLECMDERR_E_UNKNOWNGROUP The <paramref name="pguidCmdGroup" /> parameter is not null but does not specify a recognized command group.</returns>
        public int QueryStatus(ref Guid pguidCmdGroup, int cCmds, NativeMethods.OLECMD prgCmds, IntPtr pCmdText)
        {
            if((int)NativeMethods.OLECMDID.OLECMDID_SHOWSCRIPTERROR == prgCmds.cmdID)
            {   // Do nothing (suppress script errors)
                return NativeMethods.S_OK;
            }

            // Indicate that command is unknown. The command will then be handled by another IOleCommandTarget.
            return NativeMethods.OLECMDERR_E_UNKNOWNGROUP;
        }

        /// <summary>Executes the specified command.</summary>
        /// <param name="pguidCmdGroup">The GUID of the command group.</param>
        /// <param name="nCmdID">The command ID.</param>
        /// <param name="nCmdexecopt">Specifies how the object should execute the command. Possible values are taken from the <see cref="T:Microsoft.VisualStudio.OLE.Interop.OLECMDEXECOPT" /> and <see cref="T:Microsoft.VisualStudio.OLE.Interop.OLECMDID_WINDOWSTATE_FLAG" /> enumerations.</param>
        /// <param name="pvaIn">The input arguments of the command.</param>
        /// <param name="pvaOut">The output arguments of the command.</param>
        /// <returns>This method returns S_OK on success. Other possible return values include 
        /// OLECMDERR_E_UNKNOWNGROUP The <paramref name="pguidCmdGroup" /> parameter is not null but does not specify a recognized command group.
        /// OLECMDERR_E_NOTSUPPORTED The <paramref name="nCmdID" /> parameter is not a valid command in the group identified by <paramref name="pguidCmdGroup" />.
        /// OLECMDERR_E_DISABLED The command identified by <paramref name="nCmdID" /> is currently disabled and cannot be executed.
        /// OLECMDERR_E_NOHELP The caller has asked for help on the command identified by <paramref name="nCmdID" />, but no help is available.
        /// OLECMDERR_E_CANCELED The user canceled the execution of the command.</returns>
        public int Exec(ref Guid pguidCmdGroup, int nCmdID, int nCmdexecopt, object[] pvaIn, int pvaOut)
        {
            if((int)NativeMethods.OLECMDID.OLECMDID_SHOWSCRIPTERROR == nCmdID)
            {   // Do nothing (suppress script errors)
                return NativeMethods.S_OK;
            }

            // Indicate that command is unknown. The command will then be handled by another IOleCommandTarget.
            return NativeMethods.OLECMDERR_E_UNKNOWNGROUP;
        }
    }

    #endregion
}

~

/// <summary>
/// Native (unmanaged) methods, required for custom command handling for the WebBrowser control.
/// </summary>
public static class NativeMethods
{
    /// From docobj.h
    public const int OLECMDERR_E_UNKNOWNGROUP = -2147221244;

    /// <summary>
    /// From Microsoft.VisualStudio.OLE.Interop (Visual Studio 2010 SDK).
    /// </summary>
    public enum OLECMDID
    {
        /// <summary />
        OLECMDID_OPEN = 1,
        /// <summary />
        OLECMDID_NEW,
        /// <summary />
        OLECMDID_SAVE,
        /// <summary />
        OLECMDID_SAVEAS,
        /// <summary />
        OLECMDID_SAVECOPYAS,
        /// <summary />
        OLECMDID_PRINT,
        /// <summary />
        OLECMDID_PRINTPREVIEW,
        /// <summary />
        OLECMDID_PAGESETUP,
        /// <summary />
        OLECMDID_SPELL,
        /// <summary />
        OLECMDID_PROPERTIES,
        /// <summary />
        OLECMDID_CUT,
        /// <summary />
        OLECMDID_COPY,
        /// <summary />
        OLECMDID_PASTE,
        /// <summary />
        OLECMDID_PASTESPECIAL,
        /// <summary />
        OLECMDID_UNDO,
        /// <summary />
        OLECMDID_REDO,
        /// <summary />
        OLECMDID_SELECTALL,
        /// <summary />
        OLECMDID_CLEARSELECTION,
        /// <summary />
        OLECMDID_ZOOM,
        /// <summary />
        OLECMDID_GETZOOMRANGE,
        /// <summary />
        OLECMDID_UPDATECOMMANDS,
        /// <summary />
        OLECMDID_REFRESH,
        /// <summary />
        OLECMDID_STOP,
        /// <summary />
        OLECMDID_HIDETOOLBARS,
        /// <summary />
        OLECMDID_SETPROGRESSMAX,
        /// <summary />
        OLECMDID_SETPROGRESSPOS,
        /// <summary />
        OLECMDID_SETPROGRESSTEXT,
        /// <summary />
        OLECMDID_SETTITLE,
        /// <summary />
        OLECMDID_SETDOWNLOADSTATE,
        /// <summary />
        OLECMDID_STOPDOWNLOAD,
        /// <summary />
        OLECMDID_ONTOOLBARACTIVATED,
        /// <summary />
        OLECMDID_FIND,
        /// <summary />
        OLECMDID_DELETE,
        /// <summary />
        OLECMDID_HTTPEQUIV,
        /// <summary />
        OLECMDID_HTTPEQUIV_DONE,
        /// <summary />
        OLECMDID_ENABLE_INTERACTION,
        /// <summary />
        OLECMDID_ONUNLOAD,
        /// <summary />
        OLECMDID_PROPERTYBAG2,
        /// <summary />
        OLECMDID_PREREFRESH,
        /// <summary />
        OLECMDID_SHOWSCRIPTERROR,
        /// <summary />
        OLECMDID_SHOWMESSAGE,
        /// <summary />
        OLECMDID_SHOWFIND,
        /// <summary />
        OLECMDID_SHOWPAGESETUP,
        /// <summary />
        OLECMDID_SHOWPRINT,
        /// <summary />
        OLECMDID_CLOSE,
        /// <summary />
        OLECMDID_ALLOWUILESSSAVEAS,
        /// <summary />
        OLECMDID_DONTDOWNLOADCSS,
        /// <summary />
        OLECMDID_UPDATEPAGESTATUS,
        /// <summary />
        OLECMDID_PRINT2,
        /// <summary />
        OLECMDID_PRINTPREVIEW2,
        /// <summary />
        OLECMDID_SETPRINTTEMPLATE,
        /// <summary />
        OLECMDID_GETPRINTTEMPLATE
    }

    /// <summary>
    /// From Microsoft.VisualStudio.Shell (Visual Studio 2010 SDK).
    /// </summary>
    public const int S_OK = 0;

    /// <summary>
    /// OLE command structure.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public class OLECMD
    {
        /// <summary>
        /// Command ID.
        /// </summary>
        [MarshalAs(UnmanagedType.U4)]
        public int cmdID;
        /// <summary>
        /// Flags associated with cmdID.
        /// </summary>
        [MarshalAs(UnmanagedType.U4)]
        public int cmdf;
    }

    /// <summary>
    /// Enables the dispatching of commands between objects and containers.
    /// </summary>
    [ComVisible(true), Guid("B722BCCB-4E68-101B-A2BC-00AA00404770"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [ComImport]
    public interface IOleCommandTarget
    {
        /// <summary>Queries the object for the status of one or more commands generated by user interface events.</summary>
        /// <param name="pguidCmdGroup">The GUID of the command group.</param>
        /// <param name="cCmds">The number of commands in <paramref name="prgCmds" />.</param>
        /// <param name="prgCmds">An array of <see cref="T:Microsoft.VisualStudio.OLE.Interop.OLECMD" /> structures that indicate the commands for which the caller needs status information.</param>
        /// <param name="pCmdText">An <see cref="T:Microsoft.VisualStudio.OLE.Interop.OLECMDTEXT" /> structure in which to return name and/or status information of a single command. This parameter can be null to indicate that the caller does not need this information.</param>
        /// <returns>This method returns S_OK on success. Other possible return values include the following.
        /// E_FAIL The operation failed.
        /// E_UNEXPECTED An unexpected error has occurred.
        /// E_POINTER The <paramref name="prgCmds" /> argument is null.
        /// OLECMDERR_E_UNKNOWNGROUPThe <paramref name="pguidCmdGroup" /> parameter is not null but does not specify a recognized command group.</returns>
        [PreserveSig]
        [return: MarshalAs(UnmanagedType.I4)]
        int QueryStatus(ref Guid pguidCmdGroup, int cCmds, [In] [Out] NativeMethods.OLECMD prgCmds, [In] [Out] IntPtr pCmdText);

        /// <summary>Executes the specified command.</summary>
        /// <param name="pguidCmdGroup">The GUID of the command group.</param>
        /// <param name="nCmdID">The command ID.</param>
        /// <param name="nCmdexecopt">Specifies how the object should execute the command. Possible values are taken from the <see cref="T:Microsoft.VisualStudio.OLE.Interop.OLECMDEXECOPT" /> and <see cref="T:Microsoft.VisualStudio.OLE.Interop.OLECMDID_WINDOWSTATE_FLAG" /> enumerations.</param>
        /// <param name="pvaIn">The input arguments of the command.</param>
        /// <param name="pvaOut">The output arguments of the command.</param>
        /// <returns>This method returns S_OK on success. Other possible return values include 
        /// OLECMDERR_E_UNKNOWNGROUP The <paramref name="pguidCmdGroup" /> parameter is not null but does not specify a recognized command group.
        /// OLECMDERR_E_NOTSUPPORTED The <paramref name="nCmdID" /> parameter is not a valid command in the group identified by <paramref name="pguidCmdGroup" />.
        /// OLECMDERR_E_DISABLED The command identified by <paramref name="nCmdID" /> is currently disabled and cannot be executed.
        /// OLECMDERR_E_NOHELP The caller has asked for help on the command identified by <paramref name="nCmdID" />, but no help is available.
        /// OLECMDERR_E_CANCELED The user canceled the execution of the command.</returns>
        [PreserveSig]
        [return: MarshalAs(UnmanagedType.I4)]
        int Exec(ref Guid pguidCmdGroup, int nCmdID, int nCmdexecopt, [MarshalAs(UnmanagedType.LPArray)] [In] object[] pvaIn, int pvaOut);
    }
}
redcalx
źródło
Dziekuję Dziekuję Dziękuję. Wtedy tylko działające rozwiązanie w tej chwili. Wielkie dzięki: D.
Beniamin
Aż do następnej wersji IE !!
redcalx
Widzę. A które wersje IE obsługuje ta metoda?
Beniamin
Pracowałem z IE10 i 11, ale moim głównym zmartwieniem byłoby to, co się dzieje z zamiennikiem IE - Microsoft Edge.
redcalx
1
Nic się nie stanie z Microsoft Edge, ponieważ Microsoft nie pozwoli Ci osadzić Edge w aplikacji WinForms, próbując zmusić Cię do zbudowania aplikacji dla ich nowej zablokowanej platformy „Universal” - (szukaj embedna tej stronie - dev.windows.com/en-us/microsoft-edge/platform/faq/apps-engine )
Wayne
2

axwebbrowser1.Silent = true;

Arsalan
źródło
1

Oto alternatywne rozwiązanie:

class extendedWebBrowser : WebBrowser
{
    /// <summary>
    /// Default constructor which will make the browser to ignore all errors
    /// </summary>
    public extendedWebBrowser()
    {
        this.ScriptErrorsSuppressed = true;

        FieldInfo field = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
        if (field != null)
        {
             object axIWebBrowser2 = field.GetValue(this);
             axIWebBrowser2.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, axIWebBrowser2, new object[] { true });
        }
    }
}
Vlad Spreys
źródło
0

Właśnie znalazłem to:

 private static bool TrySetSuppressScriptErrors(WebBrowser webBrowser, bool value)
    {
        FieldInfo field = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
        if (field != null)
        {
            object axIWebBrowser2 = field.GetValue(webBrowser);
            if (axIWebBrowser2 != null)
            {
                axIWebBrowser2.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, axIWebBrowser2, new object[] { value });
                return true;
            }
        }

        return false;
    }

przykład użycia, aby ustawić webBrowser na cichy: TrySetSuppressScriptErrors (webBrowser, true)

Adil
źródło