Workaround BeforeNavigate2 not being fired in WPF .NET

后端 未结 1 1541
长发绾君心
长发绾君心 2020-12-06 08:22

I need to send headers with every request I transmit using the System.Windows.Controls.WebBrowser control. Using C# with .Net, due to a bug described here, the BeforeNavigat

相关标签:
1条回答
  • 2020-12-06 08:39

    Here is another approach, it uses the low-level COM connection point container interfaces to attach to the underlying DWebBrowserEvents2 source interface directly.

    Grab the full project source code from here. I don't have VS2010, so it's a VS2012 project, but it targets .NET 4.0. A compiled app is included in the Debug folder, if you're ready to try it as is.

    Here is the relevant code. It's a quick proof of concept which still may have bugs:

    using System;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Windows;
    
    namespace WpfWebBrowserEvents
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                this.Loaded += (s, e) =>
                {
                    var sink = new WebBrowserEventSink();
                    sink.Connect(this.webBrowser);
    
                    this.webBrowser.Navigate("http://example.com");
                };
            }
        }
    
        /// <summary>
        /// Handling WebBrowser ActiveX events directly
        /// by Noseratio - http://stackoverflow.com/q/20838264/1768303
        /// </summary>
    
        [ComVisible(true)]
        [ClassInterface(ClassInterfaceType.None)]
        [ComDefaultInterface(typeof(SHDocVw.DWebBrowserEvents2))]
        public class WebBrowserEventSink : SHDocVw.DWebBrowserEvents2
        {
            System.Runtime.InteropServices.ComTypes.IConnectionPoint _sinkCP = null;
            int _sinkCookie = int.MaxValue;
    
            public void Connect(System.Windows.Controls.WebBrowser webBrowser)
            {
                if (_sinkCookie != int.MaxValue)
                    throw new InvalidOperationException();
    
                var activeXInstance = webBrowser.GetType().InvokeMember("ActiveXInstance",
                    BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
                    null, webBrowser, new object[] { }) as SHDocVw.WebBrowser;
    
                var cpc = (System.Runtime.InteropServices.ComTypes.IConnectionPointContainer)activeXInstance;
                var guid = typeof(SHDocVw.DWebBrowserEvents2).GUID;
                System.Runtime.InteropServices.ComTypes.IConnectionPoint _sinkCP;
                cpc.FindConnectionPoint(ref guid, out _sinkCP);
                _sinkCP.Advise(this, out _sinkCookie);
            }
    
            public void Disconnect()
            {
                if (_sinkCookie == int.MaxValue)
                    throw new InvalidOperationException();
                _sinkCP.Unadvise(_sinkCookie);
                _sinkCookie = int.MaxValue;
                _sinkCP = null;
            }
    
            #region SHDocVw.DWebBrowserEvents2
    
            public void StatusTextChange(string Text)
            {
            }
    
            public void ProgressChange(int Progress, int ProgressMax)
            {
            }
    
            public void CommandStateChange(int Command, bool Enable)
            {
            }
    
            public void DownloadBegin()
            {
            }
    
            public void DownloadComplete()
            {
            }
    
            public void TitleChange(string Text)
            {
            }
    
            public void PropertyChange(string szProperty)
            {
            }
    
            public void BeforeNavigate2(object pDisp, ref object URL, ref object Flags, ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel)
            {
                MessageBox.Show("BeforeNavigate2: " + URL.ToString());
            }
    
            public void NewWindow2(ref object ppDisp, ref bool Cancel)
            {
            }
    
            public void NavigateComplete2(object pDisp, ref object URL)
            {
            }
    
            public void DocumentComplete(object pDisp, ref object URL)
            {
            }
    
            public void OnQuit()
            {
            }
    
            public void OnVisible(bool Visible)
            {
            }
    
            public void OnToolBar(bool ToolBar)
            {
            }
    
            public void OnMenuBar(bool MenuBar)
            {
            }
    
            public void OnStatusBar(bool StatusBar)
            {
            }
    
            public void OnFullScreen(bool FullScreen)
            {
            }
    
            public void OnTheaterMode(bool TheaterMode)
            {
            }
    
            public void WindowSetResizable(bool Resizable)
            {
            }
    
            public void WindowSetLeft(int Left)
            {
            }
    
            public void WindowSetTop(int Top)
            {
            }
    
            public void WindowSetWidth(int Width)
            {
            }
    
            public void WindowSetHeight(int Height)
            {
            }
    
            public void WindowClosing(bool IsChildWindow, ref bool Cancel)
            {
            }
    
            public void ClientToHostWindow(ref int CX, ref int CY)
            {
            }
    
            public void SetSecureLockIcon(int SecureLockIcon)
            {
            }
    
            public void FileDownload(bool ActiveDocument, ref bool Cancel)
            {
            }
    
            public void NavigateError(object pDisp, ref object URL, ref object Frame, ref object StatusCode, ref bool Cancel)
            {
            }
    
            public void PrintTemplateInstantiation(object pDisp)
            {
            }
    
            public void PrintTemplateTeardown(object pDisp)
            {
            }
    
            public void UpdatePageStatus(object pDisp, ref object nPage, ref object fDone)
            {
            }
    
            public void PrivacyImpactedStateChange(bool bImpacted)
            {
            }
    
            public void NewWindow3(ref object ppDisp, ref bool Cancel, uint dwFlags, string bstrUrlContext, string bstrUrl)
            {
            }
    
            public void SetPhishingFilterStatus(int PhishingFilterStatus)
            {
            }
    
            public void WindowStateChanged(uint dwWindowStateFlags, uint dwValidFlagsMask)
            {
            }
    
            public void NewProcess(int lCauseFlag, object pWB2, ref bool Cancel)
            {
            }
    
            public void ThirdPartyUrlBlocked(ref object URL, uint dwCount)
            {
            }
    
            public void RedirectXDomainBlocked(object pDisp, ref object StartURL, ref object RedirectURL, ref object Frame, ref object StatusCode)
            {
            }
    
            public void BeforeScriptExecute(object pDispWindow)
            {
            }
    
            public void WebWorkerStarted(uint dwUniqueID, string bstrWorkerLabel)
            {
            }
    
            public void WebWorkerFinsihed(uint dwUniqueID)
            {
            }
    
            #endregion
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题