Domanda

Ho un .NET 2.0 Controllo WebBrowser utilizzato per navigare in alcune pagine senza interazione da parte dell'utente (non chiedere... lunga storia).A causa della natura senza utente di questa applicazione, ho impostato la proprietà di ScripterrorsSsoppressa di Webbrowser Controls su True, che la documentazione inclusa con gli stati VS 2005 [...] nasconderà tutte le sue finestre di dialogo che hanno origine dal controllo ActiveX sottostante, Non solo errori di script. " IL Articolo MSDN questo però non lo menziona.Sono riuscito a cancellare l'evento NewWindow, che impedisce i popup, quindi è stato risolto.

Qualcuno ha esperienza nell'usare uno di questi e nel bloccarlo con successo Tutto finestre di dialogo, errori di script, ecc.?

MODIFICARE

Questa non è un'istanza autonoma di IE, ma un'istanza di un controllo WebBrowser che risiede in un'applicazione Windows Form.Qualcuno ha esperienza con questo controllo, o con quello sottostante, AxSHDocVW?

MODIFICA di nuovo

Scusate, ho dimenticato di menzionare questo...Sto cercando di bloccare a Avviso JavaScript(), con solo un pulsante OK.Forse posso eseguire il cast in un oggetto IHTMLDocument2 e accedere agli script in questo modo, ho usato un po' MSHTML, qualcuno lo sa?

È stato utile?

Soluzione

Questo è decisamente complicato, ma se lavori con il controllo WebBrowser, ti ritroverai a fare un sacco di cose complicate.

Questo è il modo più semplice che conosco per farlo.È necessario iniettare JavaScript per sovrascrivere la funzione di avviso...qualcosa sulla falsariga dell'iniezione di questa funzione JavaScript:

window.alert = function () { }

Ci sono molti modi per farlo, ma è assolutamente possibile farlo.Una possibilità è agganciare un'implementazione di DWebBrowserEvents2 interfaccia.Una volta fatto ciò, puoi quindi collegarti a NavigateComplete, DownloadComplete o DocumentComplete (o, come facciamo noi, qualche variazione dello stesso) e quindi chiamare un metodo InjectJavaScript che hai implementato che esegue questa sovrascrittura di window.alert metodo.

Come ho detto, hacky, ma funziona :)

Se necessario posso entrare più nel dettaglio.

Altri suggerimenti

E per un modo semplice per inserire quella riga magica di javascript, leggi come iniettare Javascript nel controllo del browser web.

Oppure usa semplicemente questo codice 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);
}

Potrebbe essere necessario personalizzare alcune cose, dai un'occhiata IDocHostUIHandler, quindi controlla alcune delle altre interfacce correlate.Puoi avere un discreto controllo, fino al punto di personalizzare la visualizzazione/interfaccia utente della finestra di dialogo (non riesco a ricordare quale interfaccia lo fa).Sono abbastanza sicuro che puoi fare quello che vuoi, ma richiede un po' di lavoro all'interno MSHTML ed essere in grado di implementare le varie COM interfacce.

Alcune altre idee:http://msdn.microsoft.com/en-us/library/aa770041.aspx

IHostDialogHelper
IDocHostShowUI

Queste potrebbero essere le cose che stai cercando di implementare.

Blocco avvisi antiproiettile:

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

Questo esempio presuppone che tu abbia Microsoft.mshtml riferimento aggiunto, "utilizzando mshtml;"nei tuoi spazi dei nomi e Navigatore è tuo Programma di navigazione in rete esempio.

Perché è a prova di proiettile?Innanzitutto, esso gestisce gli script all'interno dei frame.Allora non si blocca quando uno speciale "telaio assassino" esiste nel documento.UN "telaio assassino" è un frame che solleva un'eccezione nel tentativo di utilizzarlo come oggetto HtmlWindow.Qualsiasi "foreach" utilizzato su Document.Window.Frames causerebbe un'eccezione, quindi è necessario utilizzare un ciclo "for" più sicuro con il blocco try / catch.

Forse non è il pezzo di codice più leggibile, ma funziona con pagine della vita reale e mal formate.

webBrowser1.ScriptErrorsSuppressed = true;

Aggiungilo semplicemente alla tua funzione entry level.Dopo molte ricerche mi sono imbattuto in questo metodo e, toccando il legno, fino ad ora ha funzionato.Saluti!!

window.showModelessDialog e window.showModalDialog possono essere bloccati implementando l'interfaccia INewWindowManager, inoltre il codice seguente mostra come bloccare le finestre di dialogo di avviso 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;
    }
}

Ho appena pubblicato un articolo su Code Project che potrebbe aiutarti.

Perfavore guarda - http://www.codeproject.com/KB/shell/WebBrowserControlDialogs.aspx

Spero che questo ti aiuti.

IL InjectAlertBlocker è assolutamente corretto il codice è

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

I riferimenti necessari da aggiungere sono

  1. Aggiungi un riferimento a MSHTML, che probabilmente si chiamerà "Libreria di oggetti Microsoft HTML" Sotto COM Riferimenti.

  2. Aggiungere using mshtml; ai tuoi spazi dei nomi.

  3. Ottieni un riferimento agli elementi dello script IHTMLElement:

Quindi puoi usare il Navigated evento del browser web come:

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

Stai cercando di implementare un robot web?Ho poca esperienza nell'uso del controllo IE ospitato, ma ho completato alcuni progetti Win32 e ho provato a utilizzare il controllo IE.La disabilitazione dei popup dovrebbe essere eseguita tramite i gestori eventi del controllo come hai già fatto, ma ho scoperto che devi anche modificare "Disabilita debugging script xxxx" nelle opzioni di IE (oppure potresti modificare il registro nei tuoi codici) come cjheath già sottolineato.Tuttavia, ho anche scoperto che era necessario eseguire passaggi aggiuntivi per controllare l'URL di navigazione per eventuali contenuti scaricabili per evitare finestre di dialogo di apertura/salvataggio.Ma non so come gestire i file in streaming poiché non posso saltarli guardando solo gli URL e alla fine mi sono rivolto alla libreria Indy risparmiandomi tutti i problemi con IE.Infine, ricordo che Microsoft ha menzionato qualcosa online secondo cui IE non è progettato per essere utilizzato come controllo OLE.Secondo la mia esperienza, ogni volta che il controllo passa a una nuova pagina si verificano perdite di memoria per i programmi!

Ho avuto problemi più grandi con questo:caricamento di una pagina Web destinata alla stampa e viene visualizzata una fastidiosa finestra di dialogo Stampa.InjectBlocker era l'unico modo che funzionava, ma abbastanza inaffidabile.In determinate condizioni (sto considerando che è dovuto al fatto che il controllo del browser Web utilizza il motore IE e questo dipende dalla versione di IE installata) viene ancora visualizzata la finestra di dialogo di stampa.Questo è un grosso problema, la soluzione funziona su Win7 con IE9 installato, ma WinXP con IE8 visualizza la finestra di dialogo, qualunque cosa accada.

Credo che la soluzione stia nel modificare il codice sorgente e rimuovere il javascript di stampa, prima che il controllo esegua il rendering della pagina.Comunque l'ho provato con:DocumentText del controllo browser web e non funziona.La proprietà non è di sola lettura, ma non ha alcun effetto, quando modifico il sorgente.

La soluzione che ho trovato per il mio problema è lo script Exec:

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

Sono riuscito a iniettare il codice sopra creando un file extend WebBroswer classe e sovrascrivendo il file OnNavigated metodo.

Questo sembrava funzionare abbastanza bene:

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

Semplicemente dalle proprietà del controllo del browser:scriptErrorSupressed=vero

Il modo più semplice per farlo è:Nel :Controllo Webbrowser hai la procedura (standard) BeforeScriptExecute

(Il parametro per BeforeScriptExecute È pdispwindow )

Aggiungi questo :

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

In questo modo prima dell'esecuzione di qualsiasi script sulla finestra della pagina l'avviso verrà soppresso dal codice iniettato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top