I have an application that uses COM interop to create a spreadsheet which is opened in Excel on the client's machine. It appears, however, that the EXCEL.exe process isn't always ended when Excel is closed by the user if I look at Task Manager.
If I was saving the workbook and programmatically closing Excel, I would just use Marshal.ReleaseComObject()
to clean up, but since I'm depending on a manual close of the program, I'm not sure what to do. Any suggestions?
Possibly Excel.exe is still open because the user opened another document in the same instance of the Excell application. In that case, you should probably not kill the Excel.exe process.
If you ensure that you close all the documents you opened, and release all the objects that you created, then why is it important to you to ensure that Excel.exe terminates? Maybe the process is serving another application, or the user?
Excel cannot terminate until all its out-of-process objects are released. So it just hides its user interface and keeps running. Until either your program quits or you null all your Excel object references and the finalizer thread runs. Quitting your program would be an obvious solution. Or you can force the finalizer thread to run with:
ReleaseComObject() rarely works because it is so easy to forget an intermediary COM object reference. Like WorkBooks[index], that's an enumerator you don't see. Letting the GC make that decision for itself would be the wiser choice, if you keep running and doing work then that will happen.
There could be many reasons (including Ran's), but one I see a lot with MapPoint (another Microsoft app with a COM interface) is that you must ensure that ALL object references are cleared so that the garbage collector can clean them up. One lowly object hanging around is enough to stop the application from closing down and exiting the process list.
If I open the Excel application and workbook with:
Then I use the
wb.Close()
,app.Quit()
methods in a finally statement (or other appropriate closing event). This cleans up the Exel.exe process. No need to call theMarshall.ReleaseComObject
or GC methods.