web-dev-qa-db-ja.com

.NETWebBrowserコントロールのダイアログのブロック

.NET2.0WebBrowserコントロールを使用して、ユーザーの操作なしで一部のページをナビゲートしています(質問しないでください...長い話)。このアプリケーションはユーザーがいないため、WebBrowserコントロールのScriptErrorsSuppressedプロパティをtrueに設定しました。これにより、VS 2005に含まれるドキュメントでは、基になるActiveXコントロールに由来するすべてのダイアログボックスが非表示になります。スクリプトエラーだけではありません。」 MSDNの記事 はこれについては言及していません。ポップアップを防ぐNewWindowイベントをキャンセルすることができたので、それで問題ありません。

これらのいずれかを使用して、すべてのダイアログ、スクリプトエラーなどを正常にブロックした経験はありますか?

[〜#〜]編集[〜#〜]

これはIEのスタンドアロンインスタンスではなく、Windowsフォームアプリケーション上に存在するWebBrowserコントロールのインスタンスです。誰かがこのコントロール、または基礎となるコントロールAxSHDocVWの経験がありますか?

再度編集

申し訳ありませんが、これについて言及するのを忘れました...JavaScript alert()を、[OK]ボタンだけでブロックしようとしています。たぶん、IHTMLDocument2オブジェクトにキャストして、その方法でスクリプトにアクセスできます。MSHTMLを少し使用したことがありますが、誰か知っていますか?

19
Adam Neal

これは間違いなくハッキーですが、WebBrowserコントロールを使用して作業を行うと、ハッキーな作業をたくさん行うことになります。

これは私が知っている最も簡単な方法です。アラート関数をオーバーライドするには、JavaScriptを挿入する必要があります...このJavaScript関数の挿入に沿った何か:

window.alert = function () { }

これを行うには多くの方法がありますが、それは非常に可能です。 1つの可能性は、 DWebBrowserEvents2 インターフェイスの実装をフックすることです。これが完了したら、NavigateComplete、DownloadComplete、またはDocumentComplete(または、そのバリエーション)にプラグインして、実装したInjectJavaScriptメソッドを呼び出して、window.alertのこのオーバーライドを実行できます。方法。

私が言ったように、ハッキーですが、それは機能します:)

必要に応じて、詳細を確認できます。

7
David Mohundro

そして、JavaScriptの魔法の行を挿入する簡単な方法については、 JavaScriptをWebブラウザーコントロールに挿入する方法 をお読みください。

または、次の完全なコードを使用してください。

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

いくつかのことをカスタマイズし、IDocHostUIHandlerを見てから、他の関連するインターフェースのいくつかをチェックする必要があるかもしれません。ダイアログの表示/ UIをカスタマイズするところまで、かなりの量の制御を行うことができます(どのインターフェイスがこれを行うのか思い出せません)。やりたいことができると確信していますが、MSHTMLの内部をいじくり回して、さまざまなCOMインターフェイスを実装できる必要があります。

その他のアイデア: http://msdn.Microsoft.com/en-us/library/aa770041.aspx

IHostDialogHelper
IDocHostShowUI

これらはあなたが実装しようとしているものかもしれません。

6
Jim Crafton

防弾アラートブロッカー:

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

このサンプルは、Microsoft.mshtml参照が追加されていることを前提としています。 "using mshtml; "名前空間内でBrowserWebBrowserインスタンスです。

なぜ防弾なのですか?まず、フレーム内のスクリプトを処理します。次に、ドキュメントに特別な "キラーフレーム"が存在する場合はクラッシュしませんです。 "キラーフレーム"は、HtmlWindowオブジェクトとして使用しようとすると例外を発生させるフレームです。 Document.Window.Framesで使用される「foreach」は例外を引き起こすため、try/catchブロックでより安全な「for」ループを使用する必要があります。

おそらくそれは最も読みやすいコードではありませんが、実際の不正な形式のページで機能します。

5
Harry
webBrowser1.ScriptErrorsSuppressed = true;

それをエントリーレベルの関数に追加するだけです。たくさんの研究を経て、私はこの方法に出くわし、今まで木に触れました。乾杯!!

3
Prashant Bassi

window.showModelessDialogおよびwindow.showModalDialogは、INewWindowManagerインターフェイスを実装することでブロックできます。さらに、以下のコードは、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

私はあなたを助けるかもしれないCodeProjectに関する記事を公開しました。

参照してください- http://www.codeproject.com/KB/Shell/WebBrowserControlDialogs.aspx

お役に立てれば。

2
BimJeam

InjectAlertBlockerは絶対に正しいコードです

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

追加する必要のある参照は

  1. MSHTMLへの参照を追加します。これは、COM参照の下で "Microsoft HTML Object Library"と呼ばれます。

  2. 追加 using mshtml;名前空間に。

  3. スクリプト要素のIHTMLElementへの参照を取得します。

次に、webbrowserのNavigatedイベントを次のように使用できます。

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

単にブラウザコントロールのプロパティから:scriptErrorSupressed = true

0

これを行う最も簡単な方法は次のとおりです。:Webbrowser Controlには、プロシージャ(標準)BeforeScriptExecuteがあります。

BeforeScriptExecuteのパラメーターはpdispwindowです)

これを追加 :

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

このようにして、ページウィンドウでのスクリプトの実行前に、挿入されたコードによってアラートが抑制されます。

0
IsLeadByte

私はこれに関してより大きな問題を抱えていました:印刷用のウェブページをロードすると、迷惑な印刷ダイアログが表示されます。 InjectBlockerが機能する唯一の方法でしたが、かなり信頼性がありませんでした。特定の条件下(WebBrowserコントロールがIEエンジンを使用し、インストールされているIEバージョン)によって異なります)が原因であると考えています)、印刷ダイアログは引き続き表示されます。これは大きな問題は、ソリューションはIE9がインストールされたWin7で機能しますが、IE8を搭載したWinXPは、何があってもダイアログを表示します。

解決策は、コントロールがページをレンダリングする前に、ソースコードを変更し、印刷JavaScriptを削除することだと思います。しかし、私はそれをwebbrowserコントロールのDocumentTextプロパティで試しましたが、機能していません。プロパティは読み取り専用ではありませんが、ソースを変更しても効果はありません。

私の問題に対して私が見つけた解決策は、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

Webロボットを実装しようとしていますか?ホストされたIEコントロールを使用した経験はほとんどありませんが、IEコントロールを使用しようとしたいくつかのWin32プロジェクトを完了しました。ポップアップの無効化は次の方法で行う必要があります。すでに行ったようにコントロールのイベントハンドラーですが、IEオプションの「スクリプトデバッグxxxxを無効にする」も変更する必要があることがわかりました(または、コードでレジストリを変更できます) )cjheathがすでに指摘しているように。ただし、ダウンロード可能なコンテンツのナビゲーションURLをチェックして、これらの開く/保存ダイアログを防ぐために追加の手順を実行する必要があることもわかりました。しかし、スキップできないため、ストリーミングファイルの処理方法がわかりません。 URLだけを見て、最終的にはIndyライブラリを使用して、IEを扱う際のすべての問題を回避しました。最後に、MicrosoftがオンラインでIEが設計されていないことについて言及したことを覚えています。 OLEコントロールとして使用されます。私自身の経験によると、コントロールが新しいページに移動するたびにメモが導入されましたプログラムのリーク!

0
William

拡張されたWebBroswerクラスを作成し、OnNavigatedメソッドをオーバーライドすることで、上記のコードを挿入することができました。

これは非常にうまく機能しているようです。

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