1. 程式人生 > >C# 通過擴充套件WebBrowser捕獲網路連線錯誤資訊

C# 通過擴充套件WebBrowser捕獲網路連線錯誤資訊

--------------------------------------------------------------

--------------------------------------------------------------

想捕獲WebBrowser連線指定網站過程中發生的錯誤資訊,包括網路無法連線、404找不到網頁等等錯誤!經過網上的蒐集,找到了以下解決方案,該解決方案不會在網站連線前發出多餘的測試請求。

向Webbrowser中註冊NavigateError事件,以擴充套件webbrowser:

[ComImport, Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
TypeLibType(TypeLibTypeFlags.FHidden)]
public interface DWebBrowserEvents2
{
    [DispId(271)]
    void NavigateError(
        [In, MarshalAs(UnmanagedType.IDispatch)] object pDisp,
        [In] ref object URL, [In] ref object frame,
        [In] ref object statusCode, [In, Out] ref bool cancel);
}

自定義NavigateError事件的引數:
using System;
using System.Runtime.InteropServices;
public class WebBrowserNavigateErrorEventArgs : EventArgs
{
    private String urlValue;
    private String frameValue;
    private Int32 statusCodeValue;
    private Boolean cancelValue;
    public WebBrowserNavigateErrorEventArgs(
        String url, String frame, Int32 statusCode, Boolean cancel)
    {
        urlValue = url;
        frameValue = frame;
        statusCodeValue = statusCode;
        cancelValue = cancel;
    }
    public String Url
    {
        get { return urlValue; }
        set { urlValue = value; }
    }
    public String Frame
    {
        get { return frameValue; }
        set { frameValue = value; }
    }
    public Int32 StatusCode
    {
        get { return statusCodeValue; }
        set { statusCodeValue = value; }
    }
    public Boolean Cancel
    {
        get { return cancelValue; }
        set { cancelValue = value; }
    }
}

擴充套件webbrowser為MyWebBrowser,在程式中將webbrowser改成Mywebbrowser即可:
using System.Windows.Forms;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System;
public class MyWebBrowser : WebBrowser
{
    AxHost.ConnectionPointCookie cookie;
    MyWebBrowserEventHelper helper;
    public delegate void WebBrowserNavigateErrorEventHandler(object sender,
        WebBrowserNavigateErrorEventArgs e);

    [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
    protected override void CreateSink()
    {
        base.CreateSink();
        // Create an instance of the client that will handle the event
        // and associate it with the underlying ActiveX control.
        helper = new MyWebBrowserEventHelper(this);
        cookie = new AxHost.ConnectionPointCookie(
            this.ActiveXInstance, helper, typeof(DWebBrowserEvents2));
    }
    [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
    protected override void DetachSink()
    {
        // Disconnect the client that handles the event
        // from the underlying ActiveX control.
        if (cookie != null)
        {
            cookie.Disconnect();
            cookie = null;
        }
        base.DetachSink();
    }
    public event WebBrowserNavigateErrorEventHandler NavigateError;
    // Raises the NavigateError event.
    protected virtual void OnNavigateError(
        WebBrowserNavigateErrorEventArgs e)
    {
        if (this.NavigateError != null)
        {
            this.NavigateError(this, e);
        }
    }
    // Handles the NavigateError event from the underlying ActiveX 
    // control by raising the NavigateError event defined in this class.
    private class MyWebBrowserEventHelper :
        StandardOleMarshalObject, DWebBrowserEvents2
    {
        private MyWebBrowser parent;
        public MyWebBrowserEventHelper(MyWebBrowser parent)
        {
            this.parent = parent;
        }
        public void NavigateError(object pDisp, ref object url,
            ref object frame, ref object statusCode, ref bool cancel)
        {
            // Raise the NavigateError event.
            this.parent.OnNavigateError(
                new WebBrowserNavigateErrorEventArgs(
                (String)url, (String)frame, (Int32)statusCode, cancel));
        }
    }
}

將以上程式碼完全複製貼上到您的程式當中,然後將您原本程式中使用webbrowser的地方修改成MyWebBrowser就行了。這個時候你的mywebbrowser控制元件就有了onnavigateerror事件,在這個事件裡編寫您的錯誤處理方法。您或許需要用到錯誤訊息中的錯誤程式碼,具體錯誤程式碼請參照裡的每個錯誤程式碼代表的意義。

本人專案中所使用的錯誤處理程式碼如下:

 private void WebBrowserIE_NavigateError(object sender, WebBrowserNavigateErrorEventArgs e)
        {
            log.Debug("ERROR:----------" + e.Url);
            int code = e.StatusCode;
            // 發生錯誤時,轉向本地頁面
            if (code == -2146697211)
            {                WebBrowserIE.Navigate("本地頁面");
            }
        }

這個擴充套件方法完全不會影響webbrowser原有的任何功能,當然,您還可以按照這種思路繼續進行擴充套件,比如擴充套件使其用有mousemove事件,也是可以的!