我有一个.NET 2.0 WebBrowser控件,用于导航一些没有用户交互的页面(不要问......长篇故事)。 由于此应用程序的用户性质较少,我已将WebBrowser控件的ScriptErrorsSuppressed属性设置为true,VS 2005状态中包含的文档将“隐藏其源自底层ActiveX控件的所有对话框,不只是脚本错误。“ 但是, MSDN文章没有提到这一点。 我已经设法取消了NewWindow事件,这会阻止弹出窗口,因此需要处理。

任何人都有使用其中一个并成功阻止所有对话框,脚本错误等的经验?

编辑

这不是IE的独立实例,而是生成在Windows窗体应用程序上的WebBrowser控件的实例。 任何人都有使用此控件或底层AxSHDocVW的经验吗?

再次编辑

对不起,我忘了提这个...我试图阻止一个JavaScript警报() ,只需一个OK按钮。 也许我可以转换成IHTMLDocument2对象并以这种方式访问​​脚本,我已经使用过MSHTML了,有人都知道吗?

===============>>#1 票数:12

并且为了一个简单的方法来注入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);
}

===============>>#2 票数:7 已采纳

这绝对是hacky,但如果你使用WebBrowser控件做任何工作,你会发现自己做了很多hacky的东西。

这是我所知道的最简单的方法。 你需要注入JavaScript来覆盖警报功能......这就像注入这个JavaScript函数一样:

window.alert = function () { }

很多方法可以做到这一点 ,但这很有可能。 一种可能性是挂钩DWebBrowserEvents2接口的实现。 完成此操作后,您可以插入NavigateComplete,DownloadComplete或DocumentComplete(或者,如我们所做的,它的一些变体),然后调用您实现的InjectJavaScript方法,该方法执行窗口覆盖.alert方法。

就像我说的,hacky,但它的工作:)

如果需要,我可以详细介绍。

===============>>#3 票数:6

您可能必须自定义一些内容,查看IDocHostUIHandler ,然后查看其他一些相关的接口。 您可以进行相当多的控制,甚至可以自定义对话框显示/ ui(我无法回想起这个界面)。 我很确定你可以做你想做的事情,但它确实需要在MSHTML的内部解决问题并且能够实现各种COM接口。

其他一些想法: http//msdn.microsoft.com/en-us/library/aa770041.aspx

IHostDialogHelper
IDocHostShowUI

这些可能是您正在实施的内容。

===============>>#4 票数:5

防弹警报拦截器:

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; ”,而浏览器是您的WebBrowser实例。

为什么它是防弹的? 首先,它处理帧内的脚本 然后,当文档中存在特殊的“杀手框架”时,它不会崩溃 “杀手框架”是一种在尝试将其用作HtmlWindow对象时引发异常的框架。 Document.Window.Frames上使用的任何“foreach”都会导致异常,因此必须在try / catch块中使用更安全的“for”循环。

也许它不是最易读的代码片段,但它适用于现实生活中,格式错误的页面。

===============>>#5 票数: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;
    }
}

===============>>#6 票数:3

webBrowser1.ScriptErrorsSuppressed = true;

只需将其添加到您的入门级功能。 经过大量的研究,当我遇到这种方法,并触摸木材,直到现在它的工作。 干杯!!

===============>>#7 票数:2

我刚刚发表了一篇关于Code Project的文章,可能会对你有帮助。

请参阅 - http://www.codeproject.com/KB/shell/WebBrowserControlDialogs.aspx

希望这可以帮助。

===============>>#8 票数: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. 添加对MSHTML的引用,它将在COM引用下被称为“ Microsoft HTML Object Library ”。

  2. using mshtml;添加using mshtml; 到您的命名空间。

  3. 获取对脚本元素的IHTMLElementIHTMLElement

然后,您可以使用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();
}

===============>>#9 票数: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 );
  }
}

===============>>#10 票数:0

只需从浏览器控件属性:scriptErrorSupressed = true

===============>>#11 票数:0

最简单的方法是:在:Webbrowser控件中,您有过程(标准) BeforeScriptExecute

BeforeScriptExecute的参数是pdispwindow

添加这个:

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

通过这种方式,在页面窗口警报上的任何脚本执行将被注入的代码抑制。

===============>>#12 票数:0

我遇到了更大的问题:加载一个用于打印的网页,它显示恼人的打印对话框。 InjectBlocker是唯一可行的方法,但相当不可靠。 在某些条件下(我正在考虑它是因为WebBrowser控件使用IE引擎,这取决于安装的IE版本),仍然会出现打印对话框。 这是一个主要问题,解决方案适用于安装了IE9的Win7,但无论如何,带有IE8的WinXP都会显示对话框。

我相信解决方案是在控件呈现页面之前修改源代码并删除print 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" });

===============>>#13 票数:0

您是否尝试实施网络机器人? 我没有使用托管IE控件的经验,但我确实完成了一些尝试使用IE控件的Win32项目。 禁用弹出窗口应该通过控件的事件处理程序完成,但我发现你还需要更改IE选项中的“禁用脚本调试xxxx”(或者你可以修改代码中的注册表) cjheath已经指出了。 但是,我还发现在检查导航URL以查找任何可下载内容时需要执行额外的步骤,以防止这些打开/保存对话框。 但我不知道如何处理流文件,因为我不能单独查看网址跳过它们,最后我转向Indy库,省去了处理IE的所有麻烦。 最后,我记得微软确实在网上提到IE不能用作OLE控件。 根据我自己的经验,每次控件导航到新页面时都会为程序引入内存泄漏!

  ask by community wiki translate from so

未解决问题?本站智能推荐:

1回复

检测WebBrowser控件上的滚动

我有以下代码,很奇怪,它能工作几秒钟然后停止工作(我的事件处理程序方法停止被调用):
2回复

WebBrowser HtmlElement.GetAttribute(“href”)预先添加主机名

我的Windows窗体应用程序托管一个WebBrowser控件,该控件显示一个充满链接的页面。 我正在尝试在加载的HtmlDocument找到所有锚元素并读取它们的href属性,以便我可以在C#中提供多文件下载界面。 下面是我找到并处理锚元素的函数的简化版本: 锚标签全部被<P
1回复

如何在.NET中托管无窗口ActiveX控件

我在WinForms应用程序中托管Flash ActiveX控件。 可以,但是,背景透明性不起作用。 将控件的WMode属性设置为“透明”应该使其无窗口(就像在浏览器中一样)。 我认为它就是这样做的(因为它删除了背景色,仅保留了内容)-除了AxHost控件在其下绘制固定的白色背景。 我该
1回复

ActiveX控件中Winform用户控件中的Backgroundworker使ActiveX崩溃

我已经编写了具有可绑定属性的ActiveX控件。 ActiveX由一个对话框显示WinForms UserControl(通过CWinFormsControl <..>)组成。 当ActiveX属性更改时,将调用Usercontrol上的一个函数,然后应执行一些数据库调用并显示结
5回复

没有表单的ActiveX控件

我们需要使用第三方ActiveX控件。 唯一的问题是,我们软件中的图层是业务层,无法访问窗口或表单。 它还运行在不是STA的单独线程上(并且应该在任何线程中工作)。 我们使用此解决方法使其工作,而不是将UI与业务逻辑分开。 然后,只要我们需要引用控件,我们就会调用_myAc
2回复

如何在运行时添加ActiveX控件

我正在尝试在基于C#Windows窗体的项目的用户控件中添加activeX控件。 现在,如果我从工具菜单中添加了activeX组件,则只需使用拖放操作就可以使用activeX控件。 但是,当我尝试在运行时使用C#代码添加该代码时,则会引发以下异常: “引发了类型'System
1回复

如何在Winform的Webbrowser控件中触发__dopastback()

我正在尝试出于自动化目的在Winfrom中操纵url的html,在网页上有一个定位标记: 我如何自动触发__dopostback()? 我尝试了这个:
1回复

如何在WebBrowser控件中为表单启用自动完成功能

我一直在尝试为System.Windows.Forms.WebBrowser控件中的表单启用自动完成功能。 Internet Explorer为此提供了Internet Options->Content->Autocomplete->Use Autocomplete fo
2回复

.NET Webbrowser安全提示

我正在使用Windows窗体的.NET Web浏览控件。 每次访问该特定网页时,都会得到以下特定提示: http : //screensnapr.com/v/fS15lG.png 此nag框会干扰程序流程。 香港专业教育学院尝试了这篇文章的可接受的答案: 如何禁用Webbrowser控
1回复

C#webBrowser1.Document-按类属性查找所有元素

我在Winform应用程序C#FW4.0中使用webBrowser控件,我想找到其class属性包含某些值的所有元素。 可能吗?