My application launches and automates Excel:
Guid CLSID_ExcelApplication = ClsidFromProgID("Excel.Application");
Application xl = CoCreateInstance(CLSID_ExcelApplication);
And now we're off to the races:
Workbook wb = xl.Workbooks.Add();
Worksheet ws = wb.Worksheets[1];
ws.Name = "Monthly Expense Report";
And then normally you can .Quit
Excel:
xl.Quit();
And Excel goes away.
Enter UserControl
What is supposed to happen is that if i had the code:
Application xl = CoCreateInstance(CLSID_ExcelApplication);
xl.UserControl = false;
Workbook wb = xl.Workbooks.Add();
Worksheet ws = wb.Worksheets[1];
ws.Name = "Monthly Expense Report";
ws = null;
wb = null;
xl = null;
Then Excel is supposed to automatically close when the last outstanding reference is gone. From MSDN:
Application.UserControl property (Excel)
When the UserControl property is False for an object, that object is released when the last programmatic reference to the object is released. If this property is False, Microsoft Excel quits when the last object in the session is released.
I'll just draw attention to that important line in the documentation above:
Microsoft Excel quits when the last object in the session is released
When .UserControl
is false, Excel is supposed to automatically terminate.
The .UserControl
property defaults to false. But even if i force it to false, the out-of-process Excel automation object does not quit when the last object in the session is released:
Crashing better
This becomes a problem if there is an unexpected exception while automating. Normally in order to get rid of Excel nicely you would:
Make it visible, and let the user close it:
xl.Visible = true; xl.UserControl = true; //prevent Excel from terminating when we null our reference below xl = null
or call
.Quit
to quit:xl.Quit(); xl = null;
Except if there is a catastrophic problem, i don't get a chance to call .Quit
or call .Visible = true
. And in these cases Excel is hanging around. Over days, weeks, and months it can sometimes mean literally dozen of them.
What can i do to ensure that Excel will close when the last outstanding reference to it is gone:
Application xl = CoCreateInstance(CLSID_ExcelApplication);
xl.UserControl = false;
Workbook wb = xl.Workbooks.Add();
Worksheet ws = wb.Worksheets[1];
ws.Name = "Monthly Expense Report";
ws.Cells[1,2] = "January";
ws.Ce......CRASH