How to handle WPF WebBrowser control navigation exception

前端 未结 4 1866
慢半拍i
慢半拍i 2020-12-11 16:13

Let\'s say that WPF WebBrowser control shows some navigation errors and the page is not showing.

So there is an exception of WPF WebBrowser contro

4条回答
  •  难免孤独
    2020-12-11 16:54

    I'd been struggling with this issue for some time. I discovered a cleaner way to handle this than the accepted answer. Checking for res://ieframe.dll didn't always work for me. Sometimes the document url is null when a navigation error happened.

    Add the following References to you project:

    1. Microsoft.mshtml
    2. Microsoft.VisualStudio.OLE.Interop
    3. SHDocVw (Under COM it's called "Microsoft Internet Controls")

    Create the following helper class:

    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.InteropServices;
    using System.Windows.Controls;
    using System.Windows.Navigation;
    
    /// 
    /// Adds event handlers to a webbrowser control
    /// 
    internal class WebBrowserHelper
    {
        [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:FieldNamesMustNotContainUnderscore", Justification = "consistent naming")]
        private static readonly Guid SID_SWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
    
        internal WebBrowserHelper(WebBrowser browser)
        {
            // Add event handlers
            browser.Navigated += this.OnNavigated;
    
            // Navigate to about:blank to setup the browser event handlers in first call to OnNavigated
            browser.Source = null;
        }
    
        internal delegate void NavigateErrorEvent(string url, int statusCode);
    
        internal event NavigateErrorEvent NavigateError;
    
        private void OnNavigated(object sender, NavigationEventArgs e)
        {
            // Grab the browser and document instance
            var browser = sender as WebBrowser;
            var doc = browser?.Document;
    
            // Check if this is a nav to about:blank
            var aboutBlank = new Uri("about:blank");
            if (aboutBlank.IsBaseOf(e.Uri))
            {
                Guid serviceGuid = SID_SWebBrowserApp;
                Guid iid = typeof(SHDocVw.IWebBrowser2).GUID;
    
                IntPtr obj = IntPtr.Zero;
                var serviceProvider = doc as Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
                if (serviceProvider?.QueryService(ref serviceGuid, ref iid, out obj) == 0)
                {
                    // Set up event handlers
                    var webBrowser2 = Marshal.GetObjectForIUnknown(obj) as SHDocVw.IWebBrowser2;
                    var webBrowserEvents2 = webBrowser2 as SHDocVw.DWebBrowserEvents2_Event;
                    if (webBrowserEvents2 != null)
                    {
                        // Add event handler for navigation error
                        webBrowserEvents2.NavigateError -= this.OnNavigateError;
                        webBrowserEvents2.NavigateError += this.OnNavigateError;
                    }
                }
            }
        }
    
        /// 
        /// Invoked when navigation fails
        /// 
        [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "consistent naming")]
        [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:FieldNamesMustBeginWithLowerCaseLetter", Justification = "consistent naming")]
        private void OnNavigateError(object pDisp, ref object URL, ref object Frame, ref object StatusCode, ref bool Cancel)
        {
            this.NavigateError.Invoke(URL as string, (int)StatusCode);
        }
    }
    

    Then in your window class:

    // Init the UI
    this.InitializeComponent();
    this.WebBrowserHelper = new WebBrowserHelper(this.MyBrowserPane);
    
    // Handle nav error
    this.WebBrowserHelper.NavigateError += this.OnNavigateError;
    

提交回复
热议问题