Search code examples
excelvb.netexceptionwinforms-interop

Cleanup and close interop excel com object when exception occurs. Winforms vb.net


How to cleanup excel com objects correctly. Hanging excel process running in task manager when exception is thrown while working with the object

If there is no error then after exiting the application there is no excel.exe process left behind in taskmanager

My example code. If you comment out the error line and close the application all is good. How to handle cleanup in error cases such as this??

Imports Microsoft.Office.Interop

Public Class Form1
    Private xlApp As Excel.Application
    Private xlWorkBook As Excel.Workbook
    Private misValue As Object
    Property xlWorkSheet As Excel.Worksheet

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Try
            ''EXCEL CREATION/INITAILIAZATION
            misValue = System.Reflection.Missing.Value
            xlApp = New Microsoft.Office.Interop.Excel.Application()
            If xlApp Is Nothing Then
                MessageBox.Show("Excel is not properly installed!!")
                xlApp = Nothing
            End If
            xlWorkBook = xlApp.Workbooks.Add(misValue)


            ''WRITE TO WORKSHEET
            xlWorkSheet = xlWorkBook.Sheets("sheet1")
            xlWorkSheet.Cells(1, 1) = "THIS"
            xlWorkSheet.Cells(1, 2) = "IS"
            xlWorkSheet.Cells(1, 3) = "A"
            xlWorkSheet.Cells(1, 4) = "TEST"

            ''FORCEFULLY CAUSING ERROR, NOW THE EXCEL PROCESS HANGING IN TASK MANAGER 
            xlWorkSheet.Cells(1, -1) = "ERROR LINE"

            ''SAVE WORKSHEET
            Dim Name = DateTime.Now.ToString("s").Replace(":", "_")
            Dim Dir = AppDomain.CurrentDomain.BaseDirectory & Name & "Output.xls"
            xlApp.DisplayAlerts = False
            xlWorkBook.CheckCompatibility = False
            xlWorkBook.DoNotPromptForConvert = True
            xlWorkBook.SaveAs(Dir, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, _
                                Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue)

        Catch ex As Exception
            Dim exMsg = ex.Message
        Finally
            ''TIME TO CLEAN EXCEL STUFF 
            Cleanup()
        End Try
    End Sub

    Private Sub Cleanup()
        ReleaseObject(xlWorkSheet)
        ReleaseObject(xlWorkBook)
        xlApp.Quit()
        ReleaseObject(xlApp)
    End Sub

    Private Sub ReleaseObject(ByRef obj As Object)
        Try
            If Not IsNothing(obj) And System.Runtime.InteropServices.Marshal.IsComObject(obj) Then
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
                obj = Nothing
            End If
        Catch ex As Exception
            obj = Nothing
        Finally
            GC.Collect()
        End Try
    End Sub

End Class

Solution

  • Figured it out. xlWorkBook.close and xlApplication.Quit needed to called before releasing the object. Here is the updated Cleanup function

    Private Sub Cleanup()
        xlWorkBook.Close(False)
        xlApp.Quit()
        ReleaseObject(xlWorkSheet)
        ReleaseObject(xlWorkBook)
        ReleaseObject(xlApp)
    End Sub