19

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

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

編集

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

もう一度編集

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

4

12 に答える 12

13

JavaScript のマジック ラインを挿入する簡単な方法については、javascript を webbrowser コントロールに挿入する方法を参照してください

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

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);
}
于 2008-10-30T19:53:46.730 に答える
7

これは間違いなくハックですが、WebBrowser コントロールで作業を行うと、多くのハック作業を行っていることに気付くでしょう。

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

window.alert = function () { }

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

私が言ったように、ハッキーですが、うまくいきます:)

必要に応じて、さらに詳しく説明できます。

于 2008-09-19T12:58:18.073 に答える
6

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

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

IHostDialogHelper
IDocHostShowUI

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

于 2008-09-21T02:25:53.770 に答える
6

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

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

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

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

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

于 2012-03-21T20:07:58.463 に答える
3
webBrowser1.ScriptErrorsSuppressed = true;

それをエントリーレベルの関数に追加するだけです。多くの研究の後、私はこの方法に出会い、今まで木に触れることができました。乾杯!!

于 2011-10-26T13:10:59.853 に答える
3

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;
    }
}
于 2013-02-03T06:00:14.027 に答える
2

絶対に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. への参照を追加します。これは、参照の下に「 Microsoft HTML Object LibraryMSHTML 」と呼ばれる可能性があります。COM

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

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

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

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();
}
于 2011-04-25T16:23:05.630 に答える
0

これにはもっと大きな問題がありました。印刷用のWebページをロードすると、迷惑な印刷ダイアログが表示されます。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" });
于 2012-02-23T11:20:35.140 に答える
0

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

于 2008-09-19T01:08:10.817 に答える
0

拡張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 );
  }
}
于 2008-12-01T10:46:14.587 に答える
0

これを行う最も簡単な方法は次のとおりです。 Webbrowser コントロールには、次の手順があります (標準)。BeforeScriptExecute

( のパラメータBeforeScriptExecutepdispwindow)

これを追加 :

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

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

于 2016-03-28T08:09:29.333 に答える
0

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

于 2016-01-27T17:29:26.850 に答える