source

WPF WebBrowser 컨트롤을 사용할 때 스크립트 오류를 억제하려면 어떻게 해야 합니까?

nicesource 2023. 4. 14. 21:52
반응형

WPF WebBrowser 컨트롤을 사용할 때 스크립트 오류를 억제하려면 어떻게 해야 합니까?

WPF WebBrowser 컨트롤을 사용하여 개발자에게 흥미로운 웹 페이지를 평면 디스플레이(뉴스 피드 등)에 표시하는 WPF 응용 프로그램을 사용하고 있습니다.

문제는 HTML 스크립트 오류가 발생하여 "이 페이지에서 스크립트 실행을 중지할지" 묻는 불쾌한 IE 오류 메시지가 나타날 수 있다는 것입니다.이 에러 체크를 억제하는 방법이 있습니까?

메모: IE 설정에서 스크립트의 디버깅은 이미 비활성화되어 있습니다.

여기 제가 방금 성찰해서 만든 해결책이 있습니다.문제를 해결합니다:) activeX 오브젝트는 그때까지 사용할 수 없는 것 같기 때문에 Navigated 이벤트에서 실행합니다.

동작은 을 설정하는 것입니다.기본 activeX 개체의 사일런트 속성입니다.와 같은 것입니다.ScriptErrorsSuppressed 속성. 이는 Windows와 동등한 형식입니다.

 public void HideScriptErrors(WebBrowser wb, bool Hide) {
    FieldInfo fiComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
    if (fiComWebBrowser == null) return;
    object objComWebBrowser = fiComWebBrowser.GetValue(wb);
    if (objComWebBrowser == null) return;
    objComWebBrowser.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { Hide });
 }

이후가 아닌 언제든지 실행할 수 있는 더 나은 버전입니다.네비게이션 이벤트:

public void HideScriptErrors(WebBrowser wb, bool hide) {
    var fiComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
    if (fiComWebBrowser == null) return;
    var objComWebBrowser = fiComWebBrowser.GetValue(wb);
    if (objComWebBrowser == null) {
        wb.Loaded += (o, s) => HideScriptErrors(wb, hide); //In case we are to early
        return;
    }
    objComWebBrowser.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { hide });
}

두 번째 샘플에 문제가 있는 경우 wb를 스왑해 보십시오.wb가 로드되었습니다.네비게이트.

방금 다른 질문에서 찾았습니다. 우아하고 효과가 좋습니다.

dynamic activeX = this.webBrowser1.GetType().InvokeMember("ActiveXInstance",
                BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
                null, this.webBrowser1, new object[] { });

activeX.Silent = true;

가 WPF라는 점입니다.WebBrowser는 2.0 컨트롤과 같이 이 속성을 구현하지 않았습니다.

WindowsFormsHost에서 2.WPF를 합니다.WebBrowser ★★★★SuppressScriptErrors그래도 이를 위해서는 어플리케이션이 완전한 신뢰성이 있어야 합니다.

이상적이라고는 할 수 없지만, 현재로선 거의 유일한 선택입니다.

JavaScript 오류를 비활성화하는 흥미로운 방법도 찾았습니다.그러나 적어도 을 사용해야 합니다.Net Framework 4.0은 우아한 동적 유형을 사용하기 때문입니다.

WebBrowser 요소의 LoadCompleted 이벤트에 가입해야 합니다.

<WebBrowser x:Name="Browser" 
            LoadCompleted="Browser_OnLoadCompleted" />

그런 다음 다음과 같은 이벤트 핸들러를 작성해야 합니다.

    void Browser_OnLoadCompleted(object sender, NavigationEventArgs e)
    {
        var browser = sender as WebBrowser;

        if (browser == null || browser.Document == null)
            return;

        dynamic document = browser.Document;

        if (document.readyState != "complete")
            return;

        dynamic script = document.createElement("script");
        script.type = @"text/javascript";
        script.text = @"window.onerror = function(msg,url,line){return true;}";
        document.head.appendChild(script);
    }

@Alkampfer 답변에 코멘트로 추가하고 싶었지만 평판이 좋지 않습니다.이것은, 나에게 있어서 유효합니다(Windows 8.1, NET 4.5).

 window.Browser.LoadCompleted.Add(fun _ -> 
    window.Browser.Source <- new System.Uri("javascript:window.onerror=function(msg,url,line){return true;};void(0);"))

이 코드 샘플은 F#로 되어 있지만, 그 기능은 매우 명확합니다.

WPF 브라우저 제어 스크립트오류를 억제하려면 , 다음의 코드를 확인해 주세요.

    public MainWindow
    {
    InitializeComponent();
    WebBrowserControlView.Navigate(new Uri("https://www.hotmail.com"));
                        //The below checks for script errors.
    ViewerWebBrowserControlView.Navigated += ViewerWebBrowserControlView_Navigated;
    }

void ViewerWebBrowserControlView_Navigated(object sender, NavigationEventArgs e)
            {
    BrowserHandler.SetSilent(ViewerWebBrowserControlView, true); // make it silent
            }

public static class BrowserHandler
{
    private const string IWebBrowserAppGUID = "0002DF05-0000-0000-C000-000000000046";
    private const string IWebBrowser2GUID = "D30C1661-CDAF-11d0-8A3E-00C04FC9E26E";

    public static void SetSilent(System.Windows.Controls.WebBrowser browser, bool silent)
    {
        if (browser == null)
            MessageBox.Show("No Internet Connection");

        // get an IWebBrowser2 from the document
        IOleServiceProvider sp = browser.Document as IOleServiceProvider;
        if (sp != null)
        {
            Guid IID_IWebBrowserApp = new Guid(IWebBrowserAppGUID);
            Guid IID_IWebBrowser2 = new Guid(IWebBrowser2GUID);

            object webBrowser;
            sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out webBrowser);
            if (webBrowser != null)
            {
                webBrowser.GetType().InvokeMember("Silent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.PutDispProperty, null, webBrowser, new object[] { silent });
            }
        }
    }

}

[ComImport, Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleServiceProvider
{
    [PreserveSig]
    int QueryService([In] ref Guid guidService, [In] ref Guid riid, [MarshalAs(UnmanagedType.IDispatch)] out object ppvObject);


   }

반면 Winforms 웹 브라우저를 winforms 호스트와 함께 사용하는 경우..."SuppressScriptErrors" 속성이 true로 설정되어 있습니다.

    <WindowsFormsHost Name="WinformsHost" Grid.Row="1">
    <winForms:WebBrowser x:Name="WebBrowserControlView" ScriptErrorsSuppressed="True" AllowWebBrowserDrop="False"></winForms:WebBrowser>
</WindowsFormsHost>

이전에 이 문제를 겪었는데, 에러 처리를 억제하는 Javascript 스크립트를 주입하여 최종적으로 해결했습니다.이게 당신에게도 도움이 되길 바랍니다.

WEBBrowser 컨트롤에서 Javascript 오류 사용 안 함

너는 이 속임수를 쓸 수 있다.

vb.net

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Private Const WM_CLOSE As Short = &H10s

및 last lib를 호출합니다.

 dim hwnd 
    dim vreturnvalue
    hwnd = FindWindow(vbNullString,"script error")
    if hwnd<>0 then vreturnvalue = SendMessage(hwnd, WM_CLOSE,  &O0s, &O0s)

Wolf5의 답변은 좋지만if (objComWebBrowser == null)효과가 없는 것 같습니다.그 대신,WebBrowser을 위한 인스턴스.IsLoaded:

public void HideScriptErrors(WebBrowser webBrowser)
{
    if (!webBrowser.IsLoaded)
    {
        webBrowser.Loaded += WebBrowser_Loaded; // in case we are too early
        return;
    }

    var objComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(webBrowser);
    if (objComWebBrowser == null)
    {
        return;
    }

    objComWebBrowser.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { true });
}
private void WebBrowser_Loaded(object sender, RoutedEventArgs e)
{
    var webBrowser = sender as WebBrowser;
    webBrowser.Loaded -= WebBrowser_Loaded;
    HideScriptErrors(webBrowser);
}

또, 이 스위치를 떼어내는 것도 필요합니다.Loaded다른 탭으로 전환하여 보이지 않게 할 경우 컨트롤이 여러 번 언로드되었다가 다시 로드될 수 있으므로 이벤트 핸들러는 처음 실행한 후 다시 로드됩니다.또,if (!wb.Loaded))폴백은 여전히 중요하다.WebBrowser응용 프로그램 시작 시 표시되지 않는 다른 탭에 있는 경우 등 첫 번째 탐색에서는 아직 표시되지 않습니다.

언급URL : https://stackoverflow.com/questions/1298255/how-do-i-suppress-script-errors-when-using-the-wpf-webbrowser-control

반응형