Blocking dialogs in .NET WebBrowser control

I have a .NET 2.0 WebBrowser control used to navigate some pages with no user interaction (don't ask...long story). Because of the user-less nature of this application, I have set the WebBrowser control's ScriptErrorsSuppressed property to true, which the documentation included with VS 2005 states will [...]"hide all its dialog boxes that originate from the underlying ActiveX control, not just script errors." The MSDN article doesn't mention this, however. I have managed to cancel the NewWindow event, which prevents popups, so that's taken care of.

Anyone have any experience using one of these and successfully blocking all dialogs, script errors, etc?

EDIT

This isn't a standalone instance of IE, but an instance of a WebBrowser control living on a Windows Form application. Anyone have any experience with this control, or the underlying one, AxSHDocVW?

EDIT again

Sorry I forgot to mention this... I'm trying to block a JavaScript alert(), with just an OK button. Maybe I can cast into an IHTMLDocument2 object and access the scripts that way, I've used MSHTML a little bit, anyone know?


And for an easy way to inject that magic line of javascript, read how to inject javascript into webbrowser control.

Or just use this complete code:

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

This is most definitely hacky, but if you do any work with the WebBrowser control, you'll find yourself doing a lot of hacky stuff.

This is the easiest way that I know of to do this. You need to inject JavaScript to override the alert function... something along the lines of injecting this JavaScript function:

window.alert = function () { }

There are many ways to do this, but it is very possible to do. One possibility is to hook an implementation of the DWebBrowserEvents2 interface. Once this is done, you can then plug into the NavigateComplete, the DownloadComplete, or the DocumentComplete (or, as we do, some variation thereof) and then call an InjectJavaScript method that you've implemented that performs this overriding of the window.alert method.

Like I said, hacky, but it works :)

I can go into more details if I need to.


Bulletproof alert blocker:

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

This sample assumes you have Microsoft.mshtml reference added, "using mshtml;" in your namespaces and Browser is your WebBrowser instance.

Why is it bulletproof? First, it handles scripts inside frames. Then, it doesn't crash when a special "killer frame" exists in document. A "killer frame" is a frame which raises an exception on attempt to use it as HtmlWindow object. Any "foreach" used on Document.Window.Frames would cause an exception, so safer "for" loop must be used with try / catch block.

Maybe it's not the most readable piece of code, but it works with real life, ill-formed pages.


You may have to customize some things, take a look at IDocHostUIHandler, and then check out some of the other related interfaces. You can have a fair amount of control, even to the point of customizing dialog display/ui (I can't recall which interface does this). I'm pretty sure you can do what you want, but it does require mucking around in the internals of MSHTML and being able to implement the various COM interfaces.

Some other ideas: http://msdn.microsoft.com/en-us/library/aa770041.aspx

IHostDialogHelper
IDocHostShowUI

These may be the things you're looking at implementing.