Search code examples
c#.netinternet-explorershdocvw

DWebBrowserEvents2 event OnQuit fired multiple times


We are using an Internet Explorer object (Interop.SHDocVw, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null) to open a explorer outside a WPF application.

We need to know when the explorer closes so we handle the OnQuit event but we are receiving the event multiple times due to unknown reasons depending on the URL.

The following POC demonstrates the issue:

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");
        }
    }
}

Solution

  • It turns out that the OnQuit event is raised in more situations than just closing the browser, for example, if the page has an inside IE will raise the OnQuit as well so the OnQuit event is not reliable to know when IE has been closed so I've found a way to know it in a reliable way:

            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;
    

    This code will call the OnQuit only when the process is finished as it should do the InternetExplorer object (sigh).