代码之家  ›  专栏  ›  技术社区  ›  Ignacio Soler Garcia

DWebBrowserEvents2事件OnQuit已多次激发

  •  0
  • Ignacio Soler Garcia  · 技术社区  · 7 年前

    我们正在使用Internet Explorer对象( Interop.SHDocVw, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null )在WPF应用程序外部打开资源管理器。

    我们需要知道资源管理器何时关闭,以便处理OnQuit事件,但由于未知原因(取决于URL),我们多次收到该事件。

    以下POC演示了该问题:

    using System;
    
    namespace InternetExplorerQuitPOC
    {
        class Program
        {
            static void Main(string[] args)
            {
                do
                {
                    SHDocVw.InternetExplorer internetExplorer;
    
                    internetExplorer = new SHDocVw.InternetExplorer();
                    internetExplorer.OnQuit += OnInternetExplorerOnOnQuit;
    
                    internetExplorer.ToolBar = 1;
                    internetExplorer.StatusBar = true;
                    internetExplorer.MenuBar = true;
                    internetExplorer.Visible = true;
    
                    object url = "https://www.notariado.org";
    
                    internetExplorer.Navigate2(ref url);
                } while (Console.ReadKey() != null);
            }
    
            private static void OnInternetExplorerOnOnQuit()
            {
                Console.Out.WriteLine("Quit fired");
            }
        }
    }
    
    2 回复  |  直到 7 年前
        1
  •  0
  •   Ignacio Soler Garcia    7 年前

    事实证明,OnQuit事件不仅仅是在关闭浏览器的情况下引发的,例如,如果页面有内部IE,也会引发OnQuit,因此OnQuit事件无法可靠地知道IE何时关闭,因此我找到了一种可靠的方法:

            uint processId;
            this.internetExplorer = new InternetExplorer();
    
            NativeMethods.GetWindowThreadProcessId(new IntPtr(this.internetExplorer.HWND), out processId);
            this.internetExplorerProcess = Process.GetProcessById(Convert.ToInt32(processId));
            this.internetExplorerProcess.EnableRaisingEvents = true;
            this.internetExplorerProcess.Exited += this.OnQuit;
    

    此代码仅在进程完成时调用OnQuit,因为它应该调用InternetExplorer对象(sign)。

        2
  •  0
  •   Javi Quirós    7 年前

    对于Ignacio。

    您的解决方案不是百分之百有效的,internet explorer在打开不同浏览器时重复使用相同的进程,这会导致退出事件仅在共享该进程的最后一个浏览器关闭时运行,这可能是我们不感兴趣的浏览器。

    我实施有效解决方案的步骤如下:

    1. 创建一个流程。开始(“iexplorer”,“-noframemerging”) -noframemerging:Internet Explorer 8及更高版本。防止Internet Explorer有机会将新的框架进程合并到现有的框架进程中。这也会阻止会话合并,因为会话合并只能在合并的帧进程中进行。

      这保证了我们的导航不会与其他Internet Explorer进程合并。

    2. 将该流程与SHDocVw关联。InternetExplorer对象。

    3. 配置SHDocVw。InternetExplorer对象、窗口大小、工具栏的可见性。。。

    4. 订阅进程已退出。

    5. SHDocVw。InternetExplorer。Navigate2(“url”)

    6. 关闭新的Internet Explorer进程。

    7. 现在,我们将收到所需进程的退出事件。

    第1点是解决问题的关键。对不起,我的英语水平。 (我将发布一个示例代码)

    伊格纳西奥,我们想你:P

    推荐文章