0

我们正在使用 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");
        }
    }
}
4

2 回答 2

0

对于伊格纳西奥。

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

我为实施有效解决方案而采取的步骤是:

  1. 创建 Process.Start("iexplorer", "-noframemerging") -noframemerging:Internet Explorer 8 及更高版本。防止 Internet Explorer 机会主义地将新的框架进程合并到现有的框架进程中。这也具有防止会话合并的效果,因为会话合并只能在合并的帧进程中发生。

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

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

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

  4. 订阅进程退出。

  5. SHDocVw.InternetExplorer.Navigate2(“网址”)

  6. 关闭新的 Internet Explorer 进程。

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

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

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

于 2018-02-28T19:34:28.583 回答
0

事实证明,除了关闭浏览器之外,在更多情况下会引发 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 对象(叹气)。

于 2018-02-08T09:06:06.653 回答