it-swarm-es.tech

Bloqueo de cuadros de diálogo en el control .NET WebBrowser

Tengo un control .NET 2.0 WebBrowser utilizado para navegar por algunas páginas sin interacción del usuario (no preguntes ... historia larga). Debido a la naturaleza sin usuarios de esta aplicación, he establecido la propiedad ScriptErrorsSuppressed del control WebBrowser en true, que la documentación incluida con VS 2005 dice que "ocultará todos sus cuadros de diálogo que se originan en el control ActiveX subyacente, no solo errores de secuencia de comandos ". Sin embargo, el artículo de MSDN no menciona esto. Me las arreglé para cancelar el evento NewWindow, que evita las ventanas emergentes, así que eso se solucionó.

¿Alguien tiene alguna experiencia en el uso de uno de estos y bloquea con éxito todos diálogos, errores de script, etc.?

[~ # ~] editar [~ # ~]

Esta no es una instancia independiente de IE, sino una instancia de un control WebBrowser que vive en una aplicación de Windows Form. Alguien tiene alguna experiencia con este control, o el subyacente, AxSHDocVW ?

EDITAR de nuevo

Lo siento, olvidé mencionar esto ... Estoy tratando de bloquear una alerta de JavaScript () , con solo un botón Aceptar. Tal vez pueda convertir en un objeto IHTMLDocument2 y acceder a los scripts de esa manera, he usado MSHTML un poco, ¿alguien lo sabe?

19
Adam Neal

Esto definitivamente es hacky, pero si haces algún trabajo con el control WebBrowser, te encontrarás haciendo muchas cosas hacky.

Esta es la forma más fácil que conozco de hacer esto. Necesita inyectar JavaScript para anular la función de alerta ... algo parecido a inyectar esta función JavaScript:

window.alert = function () { }

Hay muchas formas de hacer esto , pero es muy posible hacerlo. Una posibilidad es conectar una implementación de la interfaz DWebBrowserEvents2 . Una vez hecho esto, puede conectarse a NavigateComplete, DownloadComplete o DocumentComplete (o, como hacemos nosotros, alguna variación de los mismos) y luego llamar a un método InjectJavaScript que haya implementado que realiza esta anulación de window.alert método.

Como dije, hacky, pero funciona :)

Puedo entrar en más detalles si es necesario.

7
David Mohundro

Y para una manera fácil de inyectar esa línea mágica de javascript, lea cómo inyectar javascript en el control del navegador web .

O simplemente use este código completo:

private void InjectAlertBlocker() {
    HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
    HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
    string alertBlocker = "window.alert = function () { }";
    scriptEl.SetAttribute("text", alertBlocker);
    head.AppendChild(scriptEl);
}
12
Sire

Puede que tengas que personalizar algunas cosas, echar un vistazo a IDocHostUIHandler y luego ver algunas de las otras interfaces relacionadas. Puede tener bastante control, incluso hasta el punto de personalizar la pantalla de diálogo/ui (no recuerdo qué interfaz hace esto). Estoy bastante seguro de que puede hacer lo que quiera, pero es necesario andar en el interior de MSHTML y poder implementar las diversas interfaces COM.

Algunas otras ideas: http://msdn.Microsoft.com/en-us/library/aa770041.aspx

IHostDialogHelper
IDocHostShowUI

Estas pueden ser las cosas que está buscando implementar.

6
Jim Crafton

Bloqueador de alertas a prueba de balas:

Browser.Navigated +=
    new WebBrowserNavigatedEventHandler(
        (object sender, WebBrowserNavigatedEventArgs args) => {
            Action<HtmlDocument> blockAlerts = (HtmlDocument d) => {
                HtmlElement h = d.GetElementsByTagName("head")[0];
                HtmlElement s = d.CreateElement("script");
                IHTMLScriptElement e = (IHTMLScriptElement)s.DomElement;
                e.text = "window.alert=function(){};";
                h.AppendChild(s);
            };
            WebBrowser b = sender as WebBrowser;
            blockAlerts(b.Document);
            for (int i = 0; i < b.Document.Window.Frames.Count; i++)
                try { blockAlerts(b.Document.Window.Frames[i].Document); }
                catch (Exception) { };
        }
    );

Esta muestra asume que tiene Microsoft.mshtml referencia agregada, " usando mshtml; "en sus espacios de nombres y Navegador es su instancia WebBrowser .

¿Por qué es a prueba de balas? Primero, maneja scripts dentro de marcos. Entonces, no falla cuando existe un "marco asesino" especial en el documento. Un "marco asesino" es un marco que genera una excepción al intentar usarlo como objeto HtmlWindow. Cualquier "foreach" usado en Document.Window.Frames causaría una excepción, por lo que se debe usar un bucle "for" más seguro con el bloque try/catch.

Tal vez no sea el fragmento de código más legible, pero funciona con páginas mal formadas de la vida real.

5
Harry
webBrowser1.ScriptErrorsSuppressed = true;

Solo agregue eso a su función de nivel de entrada. Después de mucha investigación es cuando me encontré con este método y toco madera hasta ahora funcionó. ¡¡Salud!!

3
Prashant Bassi

window.showModelessDialog y window.showModalDialog se pueden bloquear implementando la interfaz INewWindowManager, además, el código siguiente muestra cómo bloquear los diálogos de alerta implementando IDocHostShowUI

public class MyBrowser : WebBrowser
{

    [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
    public MyBrowser()
    {
    }

    protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
    {
        var manager = new NewWindowManagerWebBrowserSite(this);
        return manager;
    }

    protected class NewWindowManagerWebBrowserSite : WebBrowserSite, IServiceProvider, IDocHostShowUI
    {
        private readonly NewWindowManager _manager;

        public NewWindowManagerWebBrowserSite(WebBrowser Host)
            : base(Host)
        {
            _manager = new NewWindowManager();
        }

        public int ShowMessage(IntPtr hwnd, string lpstrText, string lpstrCaption, int dwType, string lpstrHelpFile, int dwHelpContext, out int lpResult)
        {
            lpResult = 0;
            return Constants.S_OK; //  S_OK Host displayed its UI. MSHTML does not display its message box.
        }

        // Only files of types .chm and .htm are supported as help files.
        public int ShowHelp(IntPtr hwnd, string pszHelpFile, uint uCommand, uint dwData, POINT ptMouse, object pDispatchObjectHit)
        {
            return Constants.S_OK; //  S_OK Host displayed its UI. MSHTML does not display its message box.
        }

        #region Implementation of IServiceProvider

        public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject)
        {
            if ((guidService == Constants.IID_INewWindowManager && riid == Constants.IID_INewWindowManager))
            {
                ppvObject = Marshal.GetComInterfaceForObject(_manager, typeof(INewWindowManager));
                if (ppvObject != IntPtr.Zero)
                {
                    return Constants.S_OK;
                }
            }
            ppvObject = IntPtr.Zero;
            return Constants.E_NOINTERFACE;
        }

        #endregion
    }
 }

[ComVisible(true)]
[Guid("01AFBFE2-CA97-4F72-A0BF-E157038E4118")]
public class NewWindowManager : INewWindowManager
{
    public int EvaluateNewWindow(string pszUrl, string pszName,
        string pszUrlContext, string pszFeatures, bool fReplace, uint dwFlags, uint dwUserActionTime)
    {

        // use E_FAIL to be the same as CoInternetSetFeatureEnabled with FEATURE_WEBOC_POPUPMANAGEMENT
        //int hr = MyBrowser.Constants.E_FAIL; 
        int hr = MyBrowser.Constants.S_FALSE; //Block
        //int hr = MyBrowser.Constants.S_OK; //Allow all
        return hr;
    }
}
3
volody

Acabo de publicar un artículo sobre Code Project que puede ayudarte.

Consulte - http://www.codeproject.com/KB/Shell/WebBrowserControlDialogs.aspx

Espero que esto ayude.

2
BimJeam

El InjectAlertBlocker es el código absolutamente correcto es

private void InjectAlertBlocker() {
    HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
    HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
    IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
    string alertBlocker = "window.alert = function () { }";
    element.text = alertBlocker;
    head.AppendChild(scriptEl);
}

Las referencias necesarias para agregar es

  1. Agregue una referencia a MSHTML, que probablemente se llamará "Biblioteca de objetos HTML de Microsoft" en las referencias COM.

  2. Agregar using mshtml; a sus espacios de nombres.

  3. Obtenga una referencia a IHTMLElement de su elemento de script:

Luego puede usar el evento Navigated del navegador web como:

private void InjectAlertBlocker()
{
    HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
    HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
    IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
    string alertBlocker = "window.alert = function () { }";
    element.text = alertBlocker;
    head.AppendChild(scriptEl);
}

private void webDest_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    InjectAlertBlocker();
}
2
abobjects.com

Simplemente desde las propiedades de control del navegador: scriptErrorSupressed = true

0

La forma más sencilla de hacerlo es: En: Control del navegador web tienes el procedimiento (estándar) BeforeScriptExecute

(El parámetro de BeforeScriptExecute es pdispwindow)

Agrega esto :

pdispwindow.execscript("window.alert = function () { }")

De esta manera, antes de cualquier ejecución de script en la ventana de página, la alerta será suprimida por el código inyectado.

0
IsLeadByte

Tuve mayores problemas con esto: cargar una página web que está destinada a imprimir y muestra un molesto cuadro de diálogo Imprimir. El InjectBlocker fue la única forma que funcionó, pero bastante poco confiable. Bajo ciertas condiciones (estoy considerando que se debe a que el control de WebBrowser usa el motor IE y esto depende de la versión IE) instalada) el cuadro de diálogo de impresión todavía aparece. Este es un problema principal, la solución funciona en Win7 con IE9 instalado, pero WinXP con IE8 muestra el cuadro de diálogo, pase lo que pase.

Creo que la solución está en modificar el código fuente y eliminar el javascript de impresión, antes de que el control muestre la página. Sin embargo, lo intenté con la propiedad DocumentText del control del navegador web y no funciona. La propiedad no es de solo lectura, pero no tiene ningún efecto cuando modifico la fuente.

La solución que encontré para mi problema es el script Exec:

string alertBlocker = "window.print = function emptyMethod() { }; window.alert = function emptyMethod() { }; window.open = function emptyMethod() { };";    
this.Document.InvokeScript("execScript", new Object[] { alertBlocker, "JavaScript" });
0
Legoless

¿Estás intentando implementar un robot web? Tengo poca experiencia en el uso del control alojado IE pero completé algunos proyectos de Win32 intenté usar el control IE. Deshabilitar las ventanas emergentes se debe hacer a través de los controladores de eventos del control como ya lo hizo, pero descubrí que también necesita cambiar el 'Desactivar la depuración del script xxxx' en las opciones IE (o puede modificar el registro en sus códigos ) como ya señaló cjheath. Sin embargo, también descubrí que se necesitaban pasos adicionales para verificar la URL de navegación en busca de contenido descargable para evitar esos cuadros de diálogo abrir/guardar. Pero no sé cómo lidiar con archivos de transmisión porque no puedo omitir ellos solo mirando las URL y al final recurrí a la biblioteca de Indy ahorrándome todos los problemas al tratar con IE. Finalmente, recuerdo que Microsoft mencionó algo en línea que IE no está diseñado para ser utilizado como un control OLE. Según mi propia experiencia, cada vez que el control navega a una nueva página introducía un memo ry fugas para los programas!

0
William

Logré inyectar el código anterior creando una clase WebBroswer extendida y anulando el método OnNavigated.

Esto pareció funcionar bastante bien:

class WebBrowserEx : WebBrowser
{
  public WebBrowserEx ()
  {
  }

  protected override void OnNavigated( WebBrowserNavigatedEventArgs e )
  {
       HtmlElement he = this.Document.GetElementsByTagName( "head" )[0];
       HtmlElement se = this.Document.CreateElement( "script" );
       mshtml.IHTMLScriptElement element = (mshtml.IHTMLScriptElement)se.DomElement;
       string alertBlocker = "window.alert = function () { }";
       element.text = alertBlocker;
       he.AppendChild( se );
       base.OnNavigated( e );
  }
}
0
Ian Hamilton