Search code examples
c#excelvstovsta

Crash while preserving excel handle


When firing up my Excel add-in, I preserve a handle to an Excel window using the following code:

ExcelWindow = new NativeWindow();
ExcelWindow.AssignHandle(new IntPtr(Application.Hwnd));

When it comes to releasing a handle, I try to do it while shutting down:

private void ThisAddInShutdown(object sender, EventArgs e)
{
  try
  {
    ExcelWindow.ReleaseHandle();
  } 
  catch
  {

  }
}

When exiting excel in Debug mode, everything works fine. Unfortunately, when running this code on a production system, I get a crash, with no ability to debug what's going on. I get a 'windows is checking this problem' window, subsequently it disappears, and that's it.

It's really not a big deal, but I don't want to annoy the users with something like this. So, does anyone have any idea what it could be and how I could debug this? Thanks.


Solution

  • My solution:

    public partial class ThisAddIn
    {
        ExcelWindow window;
    
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            window = new ExcelWindow();
    
            Application.WorkbookBeforeClose += new Excel.AppEvents_WorkbookBeforeCloseEventHandler(Application_WorkbookBeforeClose);
            Application.WorkbookActivate += new Excel.AppEvents_WorkbookActivateEventHandler(Application_WorkbookActivate);
            Application.WorkbookDeactivate += new Excel.AppEvents_WorkbookDeactivateEventHandler(Application_WorkbookDeactivate);
        }
    
        void Application_WorkbookDeactivate(Excel.Workbook Wb)
        {
            window.ReleaseHandle();
        }
    
        void Application_WorkbookActivate(Excel.Workbook Wb)
        {
            window.AssignHandle(new IntPtr(Application.Hwnd));
        }
    
        void Application_WorkbookBeforeClose(Excel.Workbook Wb, ref bool Cancel)
        {
            if (Application.Workbooks.Count > 1 || window.Handle == IntPtr.Zero) return;
            Cancel = true;
            window.ReleaseHandle();
            Dispatcher.CurrentDispatcher.BeginInvoke(new MethodInvoker(Application.Quit), null);
        }
    
        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }
    
        #region VSTO generated code
    
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }
    
        #endregion
    }