This question already has an answer here:
-
The proper way to dispose Excel com object using VB.NET?
4 answers
I'm having problems with an application I programmed in VB.NET environment that has to open an Excel file to fetch some data and then close it. The problem is that no matter what I do, in Windows' task manager the application is always there.
What the application does:
EA = New Excel.Application
OptionsSource = EA.Workbooks.Open(Filename:=myFileName, ReadOnly:=True)
wks = OptionsSource.Worksheets(1)
' reads data from cells and stores it in an array
wks = Nothing
OptionsSource.Close()
OptionsSource = Nothing
EA.Quit()
EA = Nothing
What I tried:
GC.Collect() ' after the .Close(), but really I tried it everywhere
Marshal.ReleaseComObject(Obj) ' after each Object
What I've seen do:
Application.Exit() ' seems like I cannot use it somehow
What I could do (but I haven't yet figured out how):
Process.Kill ' I'd have to find exactly the process that is started by EA = New Excel.Application and then kill it
What I cannot definitely do is to kill all the processes that are called "EXCEL" (I know how to do this, though).
How do I nuke my Excel.Application
once and for all?
This is a cautious (perhaps overly cautious) method which always works for me. I reference each COM object so I can release them later. I avoid having more than one .
when accessing a COM object i.e. instead of getting xlSheet from xlApp.Workbooks.Open(Filename:= FileName, ReadOnly:= true).Sheets(1)
, I only go one level each time, so I need the variables xlApp
, xlBooks
, xlBook
, and xlSheet
. Some people will say this is unnecessary, but it doesn't bother me because I have had success with this method.
It's similar to how you do it anyway. But you may want to at least try EA.Quit()
if nothing else.
Dim xlApp As Microsoft.Office.Interop.Excel.Application = Nothing
Dim xlBooks As Microsoft.Office.Interop.Excel.Workbooks = Nothing
Dim xlBook As Microsoft.Office.Interop.Excel.Workbook = Nothing
Dim xlSheet As Microsoft.Office.Interop.Excel.Worksheet = Nothing
Dim xlRange As Microsoft.Office.Interop.Excel.Range = Nothing
Try
xlApp = New Microsoft.Office.Interop.Excel.Application()
xlBooks = xlApp.Workbooks
xlBook = xlBooks.Open(Filename:= FileName, ReadOnly:= true)
xlSheet = xlBook.Sheets(1)
' do other stuff
Finally
GC.Collect()
GC.WaitForPendingFinalizers()
If xlRange IsNot Nothing Then Marshal.ReleaseComObject(xlRange)
If xlSheet IsNot Nothing Then Marshal.ReleaseComObject(xlSheet)
If xlBook IsNot Nothing Then
xlBook.Close(SaveChanges:= false)
Marshal.ReleaseComObject(xlBook)
End If
If xlBooks IsNot Nothing Then
xlBooks.Close()
Marshal.ReleaseComObject(xlBooks)
End If
If xlApp IsNot Nothing
xlApp.Quit()
Marshal.ReleaseComObject(xlApp)
End If
GC.Collect()
GC.WaitForPendingFinalizers()
End Try
Kill the process by its Hwnd
. Not that beautiful but it seems to work:
- Closing an Excel Workbook