DWebBrowserEvents2事件OnQuit多次触发

时间:2018-01-31 11:20:19

标签: c# .net internet-explorer shdocvw

我们正在使用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 个答案:

答案 0 :(得分:1)

事实证明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对象(叹气)。

答案 1 :(得分:0)

对于Ignacio。

您的解决方案不是100%有效,Internet Explorer在打开不同浏览器时会重复使用相同的进程,这会导致Exited事件仅在共享该进程的最后一个浏览器的Close上运行,这可能是一个没有的浏览器我们感兴趣。

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

  1. 创建Process.Start(“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. 我们现在将收到所需流程的退出事件。

  8. 第1点是解决问题的关键。抱歉我的英语水平。 (我将发布示例代码)

    Ignacio,我们想念你:P