Подтвердить что ты не робот

Блокировка диалогов в элементе управления .NET WebBrowser

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

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

ИЗМЕНИТЬ

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

РЕДАКТИРОВАТЬ снова

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

4b9b3361

Ответ 1

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

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

window.alert = function () { }

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

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

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

Ответ 2

И для простого способа ввести эту магическую строку 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);
}

Ответ 3

Блокбезопасный блокиратор предупреждений:

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

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

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

Ответ 4

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

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

IHostDialogHelper
IDocHostShowUI

Это могут быть вещи, которые вы ищете при реализации.

Ответ 6

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 Object LibraryCOM ссылках.

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

  • Получить ссылку на ваш элемент script 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();
}

Ответ 7

webBrowser1.ScriptErrorsSuppressed = true;

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

Ответ 8

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

Ответ 9

Вы пытаетесь внедрить веб-робота? У меня мало опыта использования размещенного элемента управления IE, но я выполнил несколько проектов Win32, пытавшихся использовать элемент управления IE. Отключение всплывающих окон должно выполняться с помощью обработчиков событий элемента управления, как вы это уже делали, но я обнаружил, что вам также нужно изменить "Отключить script отладку xxxx" в параметрах IE (или вы можете изменить реестр в своих кодах), как уже указывалось. Однако я также обнаружил, что необходимо выполнить дополнительные шаги по проверке навигационного URL-адреса для любого загружаемого содержимого, чтобы предотвратить открытие или сохранение диалогов. Но я не знаю, как работать с потоковыми файлами, так как я не могу их пропустить, просмотрев URL-адреса, и в конце концов я обратился к библиотеке Indy, избавив меня от всех проблем при работе с IE. Наконец, я помню, что Microsoft действительно упоминала что-то в Интернете, что IE не предназначен для использования в качестве элемента управления OLE. Согласно моему собственному опыту, каждый раз, когда элемент управления переходит на новую страницу, это создает утечку памяти для программ!

Ответ 10

Мне удалось ввести код выше, создав расширенный класс 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 );
  }
}

Ответ 11

У меня были большие проблемы с этим: загрузка веб-страницы, предназначенной для печати, и отображает раздражающий диалог печати. InjectBlocker был единственным способом, который работал, но был довольно ненадежным. При определенных условиях (я рассматриваю это из-за того, что элемент управления WebBrowser использует механизм IE, и это зависит от установленной версии IE), диалог печати все еще появляется. Это серьезная проблема, решение работает на Win7 с IE9, но WinXP с IE8 отображает диалоговое окно, несмотря ни на что.

Я считаю, что решение заключается в изменении исходного кода и удалении JavaScript-кода печати, прежде чем элемент управления отобразит страницу. Однако я пробовал это с помощью свойства DocumentText элемента управления webbrowser, и он не работает. Свойство не только для чтения, но оно не влияет на изменение источника.

Решение, которое я нашел для моей проблемы, это Exec script:

string alertBlocker = "window.print = function emptyMethod() { }; window.alert = function emptyMethod() { }; window.open = function emptyMethod() { };";    
this.Document.InvokeScript("execScript", new Object[] { alertBlocker, "JavaScript" });

Ответ 12

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

Ответ 13

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

(Параметр BeforeScriptExecute равен pdispwindow)

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

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

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