.NET WebBrowser コントロールでのダイアログのブロック
質問
.NET を持っています 2.0 WebBrowser コントロールは、ユーザーの操作なしで一部のページをナビゲートするために使用されていました (聞かないでください...長い話になります)。このアプリケーションのユーザーレスの性質のために、私はWebbrowser ControlのScripterrorsSuppredenced PropertyをTrueに設定しました。これは、VS 2005州に含まれるドキュメントが[...]「基礎となるActiveXコントロールから発生するすべてのダイアログボックスを非表示にする」スクリプトエラーだけではありません。」 MSDN の記事 ただし、これについては言及していません。ポップアップを防ぐ NewWindow イベントをキャンセルすることができたので、これで問題は解決しました。
これらのいずれかを使用してブロックに成功した経験のある人は誰でもいます 全て ダイアログ、スクリプトエラーなど?
編集
これは IE のスタンドアロン インスタンスではなく、Windows フォーム アプリケーション上に存在する WebBrowser コントロールのインスタンスです。このコントロール、またはその基礎となるコントロールを使用した経験のある人なら誰でも、 AxSHDocVW?
再度編集します
ごめんなさい、これについて言及するのを忘れていました...ブロックしようとしています JavaScript アラート(), OKボタンだけでOKです。IHTMLDocument2 オブジェクトにキャストして、その方法でスクリプトにアクセスできるかもしれません。私は MSHTML を少し使ったことがあるのですが、知っている人はいますか?
解決
これは間違いなくハッキングです。しかし、WebBrowser コントロールを使用して作業を行うと、多くのハッキングな作業を行うことになるでしょう。
これは私が知っている中で最も簡単な方法です。アラート機能をオーバーライドするには JavaScript を挿入する必要があります...この JavaScript 関数を注入するようなものです。
window.alert = function () { }
がある これを行うには多くの方法があります, しかし、それは非常に可能です。1 つの可能性は、 DWebブラウザイベント2 インターフェース。これが完了したら、NavigateComplete、DownloadComplete、または DocumentComplete (または、私たちが行っているように、そのバリエーション) にプラグインし、window.alert のオーバーライドを実行する実装した InjectJavaScript メソッドを呼び出すことができます。方法。
先ほども言いましたが、ハッキーですが、うまくいきます :)
必要であれば、さらに詳しく説明します。
他のヒント
JavaScript の魔法のラインを注入する簡単な方法については、以下を参照してください。 JavaScriptをウェブブラウザコントロールに挿入する方法.
または、次の完全なコードを使用してください。
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);
}
いくつかの項目をカスタマイズする必要があるかもしれません。 IDocHostUIHandler
, 、その他の関連インターフェイスをいくつか確認してください。ダイアログの表示/UI をカスタマイズする点に至るまで、かなりの量の制御を行うことができます (どのインターフェイスがこれを行うのか思い出せません)。やりたいことができると確信していますが、内部をいじる必要があります。 MSHTML
そしてさまざまな実装ができるようになる COM
インターフェース。
その他のアイデア:http://msdn.microsoft.com/en-us/library/aa770041.aspx
IHostDialogHelper
IDocHostShowUI
これらは、あなたが実装を検討しているものかもしれません。
防弾アラートブロッカー:
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 参照を追加しました。」mshtmlを使用します。" 名前空間内で、 ブラウザ あなたの ウェブブラウザ 実例。
なぜ防弾なのか?まず、それ フレーム内のスクリプトを処理します. 。それから クラッシュしない 特別なとき 「キラーフレーム」 文書に存在します。あ 「キラーフレーム」 HtmlWindow オブジェクトとして使用しようとすると例外が発生するフレームです。Document.Window.Frames で「foreach」を使用すると例外が発生するため、より安全な「for」ループを try / catch ブロックで使用する必要があります。
おそらくこれは最も読みやすいコードではありませんが、実際の形式の悪いページでも動作します。
webBrowser1.ScriptErrorsSuppressed = true;
それをエントリーレベルの関数に追加するだけです。いろいろ調べた結果、この方法にたどり着き、現在まで木に触れています。乾杯!!
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;
}
}
Code Project に役立つ記事を公開しました。
参照してください - http://www.codeproject.com/KB/shell/WebBrowserControlDialogs.aspx
お役に立てれば。
の 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);
}
追加する必要がある参照は、
への参照を追加します
MSHTML
, 、おそらく「」と呼ばれるでしょうMicrosoft HTML オブジェクト ライブラリ" 下COM
参考文献。追加
using mshtml;
あなたの名前空間に。スクリプト要素への参照を取得します。
IHTMLElement
:
その後、使用できます 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();
}
Web ロボットを実装しようとしていますか?私はホストされた IE コントロールを使用した経験がほとんどありませんが、IE コントロールを使用するためにいくつかの Win32 プロジェクトを完了しました。ポップアップを無効にする場合は、すでに行ったようにコントロールのイベント ハンドラーを介して行う必要がありますが、IE オプションの [スクリプト デバッグ xxxx を無効にする] も変更する必要があることがわかりました (または、コード内のレジストリを変更することもできます)。 cjheath はすでに指摘しています。ただし、ダウンロード可能なコンテンツのナビゲーション URL をチェックして、開く/保存ダイアログが表示されないようにするには、追加の手順を実行する必要があることもわかりました。しかし、URL だけを見てストリーミング ファイルをスキップすることはできないため、ストリーミング ファイルを処理する方法がわかりません。最終的に、IE を処理する際のすべてのトラブルを回避するために Indy ライブラリに頼ることにしました。最後に、Microsoft がオンラインで、IE は OLE コントロールとして使用するように設計されていないと言及していたことを覚えています。私自身の経験によると、コントロールが新しいページに移動するたびに、プログラムのメモリ リークが発生しました。
これにはさらに大きな問題がありました:印刷用の Web ページを読み込むと、煩わしい印刷ダイアログが表示されます。InjectBlocker が機能する唯一の方法でしたが、信頼性はかなり低かったです。特定の条件下では(WebBrowser コントロールが IE エンジンを使用しているためであり、これはインストールされている IE のバージョンに依存すると考えられます)、印刷ダイアログが引き続き表示されます。これは重大な問題であり、この解決策は IE9 がインストールされている Win7 では機能しますが、IE8 がインストールされている WinXP では、何があってもダイアログが表示されます。
解決策は、コントロールがページをレンダリングする前に、ソースコードを変更し、印刷JavaScriptを削除することだと思います。ただし、私はそれを次のように試しました:ウェブブラウザ コントロールの DocumentText プロパティが機能しません。このプロパティは読み取り専用ではありませんが、ソースを変更しても効果はありません。
私が見つけた問題の解決策は、Exec スクリプトです。
string alertBlocker = "window.print = function emptyMethod() { }; window.alert = function emptyMethod() { }; window.open = function emptyMethod() { };";
this.Document.InvokeScript("execScript", new Object[] { alertBlocker, "JavaScript" });
拡張ファイルを作成することで、上記のコードを挿入することができました。 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 );
}
}
ブラウザー コントロールのプロパティから簡単に:scriptErrorSupressed=true
これを行う最も簡単な方法は次のとおりです。の中に :Webブラウザコントロールの手順(標準) BeforeScriptExecute
( のパラメータ BeforeScriptExecute
は pdispwindow
)
これを追加 :
pdispwindow.execscript("window.alert = function () { }")
このようにして、ページ ウィンドウでスクリプトが実行される前に、挿入されたコードによってアラートが抑制されます。