VB.NET Excel process won't close no matter wha

2019-03-04 07:16发布

问题:

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?

回答1:

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


回答2:

Kill the process by its Hwnd. Not that beautiful but it seems to work:

  • Closing an Excel Workbook