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