Hi all,
Recently, I needed to detect when the Excel.exe was being shutdown, but I wanted to use something lighter weight than creating a class that derives from ExcelComAddIn and calling ExcelComAddInHelper.LoadComAddIn(...) in the AutoOpen method. The simplest solution I could come up with was sub-classing the main Excel application window via .NET’s NativeWindow class. This should work for all versions of Excel. Below is the code:
ExcelShutdownMonitor
using System; using System.Threading; using System.Windows.Forms; /// <summary> /// Subclasses Excel's application window, filtering window message(s) /// indicating that Excel is shuting down. /// </summary> internal sealed class ExcelShutdownMonitor : NativeWindow, IDisposable { private const int WM_DESTROY = 0x0002; private const int WM_CLOSE = 0x0010; private const int WM_QUIT = 0x0012; private long _disposedCount = 0; private long _closingEventInvokedCount = 0; public event Action ExcelClosing; public ExcelShutdownMonitor(IntPtr excelApplicationHwnd) { AssignHandle(excelApplicationHwnd); } public void Dispose() { Dispose(true); } private void Dispose(bool disposing) { if (Interlocked.Increment(ref _disposedCount) > 1) return; if (disposing) { ExcelClosing = null; GC.SuppressFinalize(this); } base.ReleaseHandle(); } ~ExcelShutdownMonitor() { Dispose(false); } protected override void WndProc(ref Message m) { if (m.Msg == WM_DESTROY || m.Msg == WM_CLOSE || m.Msg == WM_QUIT) { if (Interlocked.Increment(ref _closingEventInvokedCount) == 1) { ExcelClosing?.Invoke(); } } base.WndProc(ref m); } }Example Usage
using ExcelDna.Integration; using System; public sealed class ExcelDnaAddIn : IExcelAddIn { private ExcelShutdownMonitor _excelShutdownMonitor; public void AutoOpen() { dynamic excelApp = ExcelDnaUtil.Application; _excelShutdownMonitor = new ExcelShutdownMonitor(new IntPtr(excelApp.Hwnd)) _excelShutdownMonitor.ExcelClosing += OnExcelClosing; } public void AutoClose() { } private void OnExcelClosing() { System.Diagnostics.Debug.WriteLine("OnExcelClosing Invoked"); // ***custom logic here*** } }Hi Alexander,
This looks like a promising approach.
Note that, with the code as it is now, this only picks up when the initial workbook closes, and not when Excel will be shutting down.
Separate workbooks live in separate top-level windows, so one needs to keep that in mind.
There is some COM call that give the HWnd associated with a Workbook, as I recall.
-Govert
--
You received this message because you are subscribed to the Google Groups "Excel-DNA" group.
To unsubscribe from this group and stop receiving emails from it, send an email to exceldna+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/exceldna/64d1796f-3bdb-45c8-a7a6-ac13889ad5a5n%40googlegroups.com.