Reputation: 9160
I have the following in a program (written in VB.NET):
Imports Microsoft.Office.Interop.Excel
Public Class Form1
Dim eApp As New Excel.Application
Dim w As Excel.Workbook
w = eApp.Workbooks.Open( "path.xls", ReadOnly:=True)
.. Processing Code ..
//Attempts at killing the excel application
w.Close()
eApp.Workbooks.Close()
eApp.Quit()
End Class
When I run this a couple of times, I get a bunch of EXCEL.EXE instances in my task manager. How can I kill these processes in code? All of the ones in the code have been tried and did not work.
Upvotes: 4
Views: 3588
Reputation: 2355
//Quit Excel application
eApp.Quit();
//Release COM objects (every object you used in eApp,like workbooks, Workbook, Sheets, Worksheet)
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
// Force garbage collector cleaning
GC.Collect();
Upvotes: 0
Reputation: 1
Tagore Peethala solution is straight forward and works. Basically make sure to WorkBook.CLOSE.. then ExcelApplication.QUIT... then just look for an instance of excel running with nothing open and close it.
myExcelWorksheet = null;
if (myExcelWorkbook != null)
{
myExcelWorkbook.Close();
myExcelWorkbook = null;
}
if (myExcelApp != null)
{
myExcelApp.Quit();
myExcelApp = null;
}
foreach (System.Diagnostics.Process myProcess in System.Diagnostics.Process.GetProcessesByName("Excel"))
{
if (myProcess.MainWindowTitle == "")
{
myProcess.Kill();
}
}
Upvotes: 0
Reputation: 41
Start Excel:
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Workbook wb = xlApp.Workbooks.Open(...);
Worksheet ws = (Worksheet)wb.Worksheets[1];
Kill Excel:
System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
wb = null;
ws = null;
uint idProcess;
GetWindowThreadProcessId((IntPtr)xlApp.Hwnd, out idProcess);
xlApp.DisplayAlerts = false;
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
xlApp = null;
xlApp = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
Process processo = null;
try
{
processo = Process.GetProcessById((int)idProcess);
}
catch { }
if (processo != null)
processo.Kill();
Upvotes: 1
Reputation:
After ExcelApplication.Quit() add the following code.
It will kill the excel application from process.
Process[] Proc = Process.GetProcessesByName("Excel");
foreach (Process p in Proc)
{
if (p.MainWindowTitle == "")
p.Kill();
}
Upvotes: 1
Reputation: 6655
Use the Using block
Using eApp As New Excel.Application
Using w As Excel.Workbook
w = eApp.Workbooks.Open( "path.xls", ReadOnly:=True)
.. Processing Code ..
//Attempts at killing the excel application
w.Close()
eApp.Workbooks.Close()
eApp.Quit()
End Using
End Using
Similar to try/finally block with a disposal in the finally, this will automatically dispose the Excel.Application and Excel.Workbook.
As mentioned in other post, System.Runtime.InteropServices.Marshal.ReleaseComObject(eApp) might also be necessary????
Upvotes: 0
Reputation: 124696
In order to make Excel exit you need to call Application.Quit, and use one of the following techniques.
Call Marshal.ReleaseComObject on every Excel object you instantiate. There's a KnowledgeBase article that describes how to do it. For example in your sample code "eApp.Workbooks.Open" instantiates a Workbooks object without assigning a variable to it. You need to assign a variable as described in the KB article so you can subsequently release it. The catch is that with anything but the simplest automation scenarios it is very difficult to be sure you always release all such objects in all code paths (e.g. by using try/finally to ensure they are released when an exception is thrown).
Call GC.Collect and GC.WaitForPendingFinalizers after you release the last Excel object. Some people have suggested that you may need to do this twice.
Upvotes: 2
Reputation: 5555
I posted a solution to this a few days ago: Killing Excel.EXE on server
Same method as StingyJack mentions; the only one I know to really work.
Upvotes: 0
Reputation: 4169
loop the below line of code until the result is zero or less
System.Runtime.InteropServices.Marshal.ReleaseComObject(eApp)
or check out this link
Upvotes: 3
Reputation: 19469
I had to do this a while back in NET 1.1, so please forgive the rust.
On the eApp, there was a Hwind (a win32 window handle - http://msdn.microsoft.com/en-us/library/bb255823.aspx ) or similar object. I had to use that and a pInvoke (http://www.pinvoke.net/default.aspx/user32.GetWindowThreadProcessId ) to get the process id. With that I was able to do a Process.Kill() on the exe.
There maybe a better way to do it now, but this should work.
Upvotes: 3