.NET2.0WebBrowserコントロールを使用して、ユーザーの操作なしで一部のページをナビゲートしています(質問しないでください...長い話)。このアプリケーションはユーザーがいないため、WebBrowserコントロールのScriptErrorsSuppressedプロパティをtrueに設定しました。これにより、VS 2005に含まれるドキュメントでは、基になるActiveXコントロールに由来するすべてのダイアログボックスが非表示になります。スクリプトエラーだけではありません。」 MSDNの記事 はこれについては言及していません。ポップアップを防ぐNewWindowイベントをキャンセルすることができたので、それで問題ありません。
これらのいずれかを使用して、すべてのダイアログ、スクリプトエラーなどを正常にブロックした経験はありますか?
[〜#〜]編集[〜#〜]
これはIEのスタンドアロンインスタンスではなく、Windowsフォームアプリケーション上に存在するWebBrowserコントロールのインスタンスです。誰かがこのコントロール、または基礎となるコントロールAxSHDocVWの経験がありますか?
再度編集
申し訳ありませんが、これについて言及するのを忘れました...JavaScript alert()を、[OK]ボタンだけでブロックしようとしています。たぶん、IHTMLDocument2オブジェクトにキャストして、その方法でスクリプトにアクセスできます。MSHTMLを少し使用したことがありますが、誰か知っていますか?
これは間違いなくハッキーですが、WebBrowserコントロールを使用して作業を行うと、ハッキーな作業をたくさん行うことになります。
これは私が知っている最も簡単な方法です。アラート関数をオーバーライドするには、JavaScriptを挿入する必要があります...このJavaScript関数の挿入に沿った何か:
window.alert = function () { }
これを行うには多くの方法がありますが、それは非常に可能です。 1つの可能性は、 DWebBrowserEvents2 インターフェイスの実装をフックすることです。これが完了したら、NavigateComplete、DownloadComplete、またはDocumentComplete(または、そのバリエーション)にプラグインして、実装したInjectJavaScriptメソッドを呼び出して、window.alertのこのオーバーライドを実行できます。方法。
私が言ったように、ハッキーですが、それは機能します:)
必要に応じて、詳細を確認できます。
そして、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);
}
いくつかのことをカスタマイズし、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参照が追加されていることを前提としています。 "using mshtml; "名前空間内でBrowserはWebBrowserインスタンスです。
なぜ防弾なのですか?まず、フレーム内のスクリプトを処理します。次に、ドキュメントに特別な "キラーフレーム"が存在する場合はクラッシュしませんです。 "キラーフレーム"は、HtmlWindowオブジェクトとして使用しようとすると例外を発生させるフレームです。 Document.Window.Framesで使用される「foreach」は例外を引き起こすため、try/catchブロックでより安全な「for」ループを使用する必要があります。
おそらくそれは最も読みやすいコードではありませんが、実際の不正な形式のページで機能します。
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;
}
}
私はあなたを助けるかもしれないCodeProjectに関する記事を公開しました。
参照してください- 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
への参照を追加します。これは、COM
参照の下で "Microsoft HTML Object Library"と呼ばれます。
追加 using mshtml;
名前空間に。
スクリプト要素の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();
}
単にブラウザコントロールのプロパティから:scriptErrorSupressed = true
これを行う最も簡単な方法は次のとおりです。:Webbrowser Controlには、プロシージャ(標準)BeforeScriptExecute
があります。
(BeforeScriptExecute
のパラメーターはpdispwindow
です)
これを追加 :
pdispwindow.execscript("window.alert = function () { }")
このようにして、ページウィンドウでのスクリプトの実行前に、挿入されたコードによってアラートが抑制されます。
私はこれに関してより大きな問題を抱えていました:印刷用のウェブページをロードすると、迷惑な印刷ダイアログが表示されます。 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" });
Webロボットを実装しようとしていますか?ホストされたIEコントロールを使用した経験はほとんどありませんが、IEコントロールを使用しようとしたいくつかのWin32プロジェクトを完了しました。ポップアップの無効化は次の方法で行う必要があります。すでに行ったようにコントロールのイベントハンドラーですが、IEオプションの「スクリプトデバッグxxxxを無効にする」も変更する必要があることがわかりました(または、コードでレジストリを変更できます) )cjheathがすでに指摘しているように。ただし、ダウンロード可能なコンテンツのナビゲーションURLをチェックして、これらの開く/保存ダイアログを防ぐために追加の手順を実行する必要があることもわかりました。しかし、スキップできないため、ストリーミングファイルの処理方法がわかりません。 URLだけを見て、最終的にはIndyライブラリを使用して、IEを扱う際のすべての問題を回避しました。最後に、MicrosoftがオンラインでIEが設計されていないことについて言及したことを覚えています。 OLEコントロールとして使用されます。私自身の経験によると、コントロールが新しいページに移動するたびにメモが導入されましたプログラムのリーク!
拡張された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 );
}
}