문제

.NET이 있습니다 2.0 사용자 상호 작용 없이 일부 페이지를 탐색하는 데 사용되는 WebBrowser 컨트롤입니다(묻지 마세요...긴 이야기입니다).이 응용 프로그램의 사용자가없는 특성으로 인해 Webbrowser Control의 스크립트러링 속성을 True로 설정했습니다. VS 2005 상태에 포함 된 문서는 [...] "기본 ActiveX 컨트롤에서 유래 한 모든 대화 상자를 숨길 것입니다. 스크립트 오류만이 아닙니다. " 그만큼 MSDN 기사 그러나 이에 대해서는 언급하지 않습니다.팝업을 방지하는 NewWindow 이벤트를 취소하여 문제가 해결되었습니다.

누구나 이 중 하나를 사용하여 성공적으로 차단한 경험이 있습니다. 모두 대화 상자, 스크립트 오류 등?

편집하다

이는 IE의 독립 실행형 인스턴스가 아니라 Windows Form 응용 프로그램에 있는 WebBrowser 컨트롤의 인스턴스입니다.누구나 이 컨트롤이나 기본 컨트롤에 대한 경험이 있습니다. 도끼SHDocVW?

다시 편집

죄송합니다. 이 내용을 언급하는 것을 잊어버렸습니다...차단하려고 하는데 자바스크립트 경고(), 확인 버튼만 있으면 됩니다.아마도 IHTMLDocument2 개체로 캐스팅하고 그런 식으로 스크립트에 액세스할 수 있을 것입니다. MSHTML을 조금 사용해 본 적이 있는 분 계시나요?

도움이 되었습니까?

해결책

이는 확실히 해킹적인 작업이지만 WebBrowser 컨트롤을 사용하여 작업을 수행하면 많은 해킹 작업을 수행하게 됩니다.

이것이 내가 아는 가장 쉬운 방법입니다.경고 기능을 무시하려면 JavaScript를 삽입해야 합니다...이 JavaScript 함수를 주입하는 라인을 따라 뭔가:

window.alert = function () { }

있다 이를 수행하는 여러 가지 방법, 그러나 그것은 매우 가능합니다.한 가지 가능성은 다음의 구현을 연결하는 것입니다. DWebBrowserEvents2 상호 작용.이 작업이 완료되면 NavigateComplete, DownloadComplete 또는 DocumentComplete(또는 우리가 하는 것처럼 일부 변형)에 연결한 다음 window.alert를 재정의하기 위해 구현한 InjectJavaScript 메서드를 호출할 수 있습니다. 방법.

내가 말했듯이 해키하지만 작동합니다 :)

필요한 경우 더 자세히 설명할 수 있습니다.

다른 팁

그리고 자바스크립트의 마법 라인을 삽입하는 쉬운 방법을 보려면 다음을 읽어보세요. 웹브라우저 컨트롤에 자바스크립트를 삽입하는 방법.

아니면 다음 전체 코드를 사용하세요.

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

이 샘플에서는 마이크로소프트.mshtml 참조가 추가되었습니다."mshtml을 사용하여;"를 네임스페이스에 넣고 브라우저 너의 웹 브라우저 사례.

왜 방탄인가요?첫째, 그것은 프레임 내부의 스크립트를 처리합니다..그러면, 그것은 충돌하지 않습니다 특별한 때 "킬러 프레임" 문서에 존재합니다.ㅏ "킬러 프레임" 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;
    }
}

방금 Code Project에 도움이 될 만한 기사를 게시했습니다.

꼭 봐주세요 - 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);
}

추가해야 할 참조는 다음과 같습니다.

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

웹 로봇을 구현하려고 하시나요?저는 호스팅된 IE 컨트롤을 사용한 경험이 거의 없지만 IE 컨트롤을 사용하려고 시도한 몇 가지 Win32 프로젝트를 완료했습니다.팝업 비활성화는 이미 수행한 것처럼 컨트롤의 이벤트 핸들러를 통해 수행되어야 하지만 IE 옵션에서 '스크립트 디버깅 xxxx 비활성화'도 변경해야 한다는 것을 알았습니다(또는 코드에서 레지스트리를 수정할 수 있음). cjheath는 이미 지적했습니다.그러나 열기/저장 대화 상자를 방지하려면 다운로드 가능한 콘텐츠에 대한 탐색 URL을 확인하는 데 추가 단계를 수행해야 한다는 점도 발견했습니다.하지만 URL만 보고는 건너뛸 수 없기 때문에 스트리밍 파일을 처리하는 방법을 모르고 결국 Indy 라이브러리를 사용하여 IE를 처리하는 데 필요한 모든 문제를 해결했습니다.마지막으로 Microsoft가 IE가 OLE 컨트롤로 사용하도록 설계되지 않았다는 내용을 온라인에서 언급한 것을 기억합니다.내 경험에 따르면 컨트롤이 새 페이지로 이동할 때마다 프로그램에 대한 메모리 누수가 발생했습니다!

나는 이것에 더 큰 문제가 있었습니다:인쇄용 웹페이지를 로드하면 짜증나는 인쇄 대화 상자가 표시됩니다.InjectBlocker가 작동하는 유일한 방법이었지만 상당히 신뢰할 수 없었습니다.특정 조건(WebBrowser 컨트롤이 IE 엔진을 사용하기 때문에 설치된 IE 버전에 따라 다름)에서 인쇄 대화 상자가 계속 나타납니다.이는 심각한 문제입니다. 솔루션은 IE9가 설치된 Win7에서 작동하지만 IE8이 설치된 WinXP는 무슨 일이 있어도 대화 상자를 표시합니다.

저는 컨트롤이 페이지를 렌더링하기 전에 소스 코드를 수정하고 인쇄 자바스크립트를 제거하는 것이 해결책이라고 생각합니다.그러나 나는 다음과 같이 시도했습니다.웹 브라우저 컨트롤의 DocumentText 속성이 작동하지 않습니다.속성은 읽기 전용이 아니지만 소스를 수정해도 아무런 영향을 미치지 않습니다.

내 문제에 대해 찾은 해결책은 Exec 스크립트입니다.

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

확장된 코드를 생성하여 위의 코드를 삽입했습니다. 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 );
  }
}

간단히 브라우저 컨트롤 속성에서:scriptErrorSuppressed=true

이를 수행하는 가장 쉬운 방법은 다음과 같습니다.에서 :웹 브라우저 제어 절차가 있습니다 (표준) BeforeScriptExecute

( 매개변수는 BeforeScriptExecute ~이다 pdispwindow )

이거 추가 해봐 :

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

이런 방식으로 페이지 창 경고의 스크립트 실행이 삽입된 코드에 의해 억제됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top