Блокировка диалогов в .NET WebBrowser - PullRequest
19 голосов
/ 17 сентября 2008

У меня есть .NET 2.0 Элемент управления WebBrowser, используемый для навигации по некоторым страницам без взаимодействия с пользователем (не спрашивайте ... длинная история). Из-за бесполезной природы этого приложения я установил для свойства ScriptErrorsSuppressed элемента управления WebBrowser значение true, которое в документации, включенной в состояния VS 2005, [...] будет скрывать все его диалоговые окна, которые происходят из базового элемента управления ActiveX не только ошибки скрипта. " Однако в статье MSDN об этом не говорится. Мне удалось отменить событие NewWindow, которое предотвращает всплывающие окна, поэтому об этом позаботились.

Кто-нибудь имеет опыт использования одного из них и успешно блокирует все диалоги, ошибки скриптов и т. Д.?

EDIT

Это не автономный экземпляр IE, а экземпляр элемента управления WebBrowser, находящийся в приложении Windows Form. Кто-нибудь имеет опыт работы с этим элементом управления, или с базовым, AxSHDocVW ?

ИЗМЕНИТЬ снова

Извините, я забыл упомянуть об этом ... Я пытаюсь заблокировать предупреждение JavaScript () , просто нажав кнопку ОК. Может быть, я могу привести в объект IHTMLDocument2 и получить доступ к сценариям таким образом, я немного использовал MSHTML, кто-нибудь знает?

Ответы [ 13 ]

12 голосов
/ 30 октября 2008

И для простого способа внедрить эту волшебную линию 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);
}
7 голосов
/ 19 сентября 2008

Это определенно хакерский, но если вы будете работать с элементом управления WebBrowser, вы обнаружите, что делаете много хакерских вещей.

Это самый простой из известных мне способов сделать это. Вам нужно внедрить JavaScript, чтобы переопределить функцию оповещения ... что-то похожее на внедрение этой функции JavaScript:

window.alert = function () { }

Есть много способов сделать это , но это очень возможно сделать. Одна из возможностей - подключить реализацию интерфейса DWebBrowserEvents2 . Как только это будет сделано, вы можете подключить NavigateComplete, DownloadComplete или DocumentComplete (или, как мы делаем, некоторые их варианты) и затем вызвать реализованный метод InjectJavaScript, который выполняет это переопределение window.alert метод.

Как я уже сказал, хак, но это работает:)

Я могу вдаваться в подробности, если мне нужно.

6 голосов
/ 21 сентября 2008

Возможно, вам придется настроить некоторые вещи, взглянуть на IDocHostUIHandler, а затем проверить некоторые другие связанные интерфейсы. Вы можете иметь достаточное количество контроля, даже до настройки диалогового окна / пользовательского интерфейса (я не могу вспомнить, какой интерфейс делает это). Я почти уверен, что вы можете делать то, что хотите, но для этого нужно обойти все внутренности MSHTML и иметь возможность реализовать различные COM интерфейсы.

Некоторые другие идеи: http://msdn.microsoft.com/en-us/library/aa770041.aspx

IHostDialogHelper
IDocHostShowUI

Это может быть то, что вы ищете для реализации.

5 голосов
/ 22 марта 2012

Пуленепробиваемый блокировщик предупреждений:

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; " в ваших пространствах имен и Браузер - ваш WebBrowser экземпляр.

Почему это пуленепробиваемый? Во-первых, он обрабатывает скрипты внутри фреймов . Тогда не падает , когда в документе существует специальный «кадр убийцы» . «киллерный фрейм» - это фрейм, который вызывает исключение при попытке использовать его в качестве объекта HtmlWindow. Любой «foreach», используемый в Document.Window.Frames, вызовет исключение, поэтому более безопасный цикл «for» должен использоваться с блоком try / catch.

Возможно, это не самый читаемый кусок кода, но он работает с реальными, плохо сформированными страницами.

3 голосов
/ 03 февраля 2013

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;
    }
}
3 голосов
/ 26 октября 2011
webBrowser1.ScriptErrorsSuppressed = true;

Просто добавьте это к вашей функции начального уровня. После многих исследований это когда я наткнулся на этот метод, и коснуться дерева до сих пор его работали. Ура !! * * 1002

2 голосов
/ 25 апреля 2011

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, которая, вероятно, будет называться " Библиотека объектов Microsoft HTML " под COM ссылками.

  2. Добавьте using mshtml; к своим пространствам имен.

  3. Получить ссылку на элемент скрипта 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();
}
2 голосов
/ 24 ноября 2008

Я только что опубликовал статью о Code Project, которая может вам помочь.

Пожалуйста, смотрите - http://www.codeproject.com/KB/shell/WebBrowserControlDialogs.aspx

Надеюсь, это поможет.

0 голосов
/ 28 марта 2016

Самый простой способ сделать это: В: Webbrowser Control у вас есть процедура (стандартная) BeforeScriptExecute

(параметр для BeforeScriptExecute равен pdispwindow)

Добавить это:

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

Таким образом, перед выполнением любого скрипта в окне страницы предупреждение будет подавлено введенным кодом.

0 голосов
/ 27 января 2016

Просто из свойств элемента управления браузера: scriptErrorSupressed = true

...