views:

600

answers:

6

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.

+3  A: 

loop the below line of code until the result is zero or less

System.Runtime.InteropServices.Marshal.ReleaseComObject(eApp)

or check out this link

Oscar Cabrero
I actually just found this too. Great link, btw.
Anthony Potts
Hi, I think this solution will not work if Excel is displaying a modal dialog. In such a case you will have to kill the Excel process as described by StingyJackIt's good practice in general to disable alerts (Application.DisplayAlerts = False) when automating as well as automatic recalculation.
0xA3
+3  A: 

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.

StingyJack
A: 

I posted a solution to this a few days ago: http://stackoverflow.com/questions/51462/killing-excelexe-on-server#312513

Same method as StingyJack mentions; the only one I know to really work.

Vincent Van Den Berghe
+1  A: 

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.

Joe
A: 

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????

Greg Ogle
A: 

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();
            }