Why is Microsoft.Office.Interop.Excel.Application.Quit () leaving the background process?

The following code leaves the Microsoft Excel background process running until my program exits:

var excelApplication = new Application(); var workbooks = excelApplication.Workbooks; var workbook = excelApplication.Workbooks.Open(file.FullName); workbook.Close(); excelApplication.Workbooks.Close(); excelApplication.Quit(); Marshal.ReleaseComObject(workbook); Marshal.ReleaseComObject(workbooks); Marshal.ReleaseComObject(excelApplication); 

Why? What am I missing?

+8
c # excel office-interop excel-interop
source share
3 answers

Got it!

application.Workbooks! = application.Workbooks

This property does not expose a variable; it generates a value. Therefore, every time I access the Workbooks property, I create a new COM object.

I fixed the code and everything is fine. Thanks to everyone.

 var excelApplication = new Application(); var workbooks = excelApplication.Workbooks; var workbook = workbooks.Open(pathToExcelWorkbook); // Fixed workbook.Close(); workbooks.Close(); excelApplication.Quit(); Marshal.ReleaseComObject(workbook); Marshal.ReleaseComObject(workbooks); Marshal.ReleaseComObject(excelApplication); 
+16
source share

This is a common problem with Office applications. All Excel / Automation applications should systematically release references to Excel objects when they are no longer needed. Failure to systematically release references to Excel objects can prevent Microsoft Office Excel from shutting down properly. For more information, see Systematic Deletion of Objects . This is related to Outlook, but the same principles can apply to all Office applications.

Use System.Runtime.InteropServices.Marshal.ReleaseComObject to free an Excel object when you finish it. Then set the Nothing variable in Visual Basic (null in C #) to free the reference to the object.

+5
source share

THIS IS THE WRONG WAY TO ACT IT , but this is the easiest way to fix the problem :

  [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); private Application _excelApp; private Workbook _excelWorkBook; private Worksheet _excelSheet; private void CloseExcelApp() { int hWnd = _excelApp.Application.Hwnd; uint processID; GetWindowThreadProcessId((IntPtr)hWnd, out processID); Process.GetProcessById((int)processID).Kill(); _excelWorkBook = null; _excelApp = null; _excelSheet = null; } 

all you need to do is to initialize all uninitialized variables when you need to work with it and call CloseExcelApp () when you need to close the application.

0
source share

All Articles