[VB.NET] Kill Process Excel


Description
      If you use vb.net to generate excel but the process excel cannot be terminate, this would be a serous problem , because if you do the work repeatedly excel process will accumulate and this will make the memory becomes full the effect of windows can be hang and it's dangerous. to prevent this we must kill the excel process but if you open another excel it will closed too. the solution is simply that you must find the process id of the object, and kill that object by id.

How to
1. i will give sample code below (create object excel)

        Dim oexcel As Object
        Dim obook As Object
        Dim osheet As Object

       'create Object excel
        Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
        oexcel = CreateObject("Excel.Application")
        obook = oexcel.workbooks.Add
        osheet = obook.worksheets(1)

       'Create Header First  
       osheet.Range("A1").Value = "Header 1"
       osheet.Range("B1").Value = "Header 2"
            
       osheet.Range("A2").Value = "Cell 1"
       osheet.Range("B2").Value = "Cell 2"

       oexcel.DisplayAlerts = False
       obook.SaveAs("D:\myfile.xls")
       oexcel.Quit()
       oexcel = Nothing
       MsgBox("Extract to Excel Complete, file save in :" & "D:\myfile.xls")

* the code above only create object excel and write some value into file, but it not close the process yet. to create kill excel process by PiD we must create sub and call it.

2. Create sub "killCurrentExcel()" 
    - first step we must declare win32 API. create a module and write this :
          'win32 API
    Public Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hWnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
    Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr

   - After win32 API has been declare , create the function : 
      Public Sub killCurrentExcel (ByVal oexcel As Object)
        Dim proc As System.Diagnostics.Process
        Dim intPID As Integer
        Dim intResult As Integer
        Dim iHandle As IntPtr
        Dim strVer As String

        strVer = oexcel.Version
        iHandle = IntPtr.Zero
        If CInt(strVer) > 9 Then
            iHandle = New IntPtr(CType(oexcel.Parent.Hwnd, Integer))
        Else
            iHandle = FindWindow(Nothing, oexcel.Caption)
        End If
        oexcel.Workbooks.Close()
        oexcel.Quit()
        Marshal.ReleaseComObject(oexcel)
        oexcel = Nothing
        intResult = GetWindowThreadProcessId(iHandle, intPID)
        proc = System.Diagnostics.Process.GetProcessById(intPID)
        proc.Kill()
      End Sub
      
3. Call killCurrentExcel() before messagebox of the excel with format : 
      killCurrentExcel("your object excel here")  so it will be "killCurrentExcel(oexcel)"

4. Here's the full listing :
    ' sub for generate excel
    Public Sub generateExcel()
        Dim oexcel As Object
        Dim obook As Object
        Dim osheet As Object

       'create Object excel
        oexcel = CreateObject("Excel.Application")
        obook = oexcel.workbooks.Add
        osheet = obook.worksheets(1)
        Try
            'Create Header First  
            osheet.Range("A1").Value = "Header 1"
            osheet.Range("B1").Value = "Header 2"
            
            osheet.Range("A2").Value = "Cell 1"
            osheet.Range("B2").Value = "Cell 2"

            oexcel.DisplayAlerts = False
            obook.SaveAs("D:\myfile.xls")
            oexcel.Quit()
            killCurrentExcel(oexcel)
            oexcel = Nothing
            MsgBox("Extract to Excel Complete, file save in :" & "D:\myfile.xls")
    end sub

    'sub for kill process by PiD
    Public Sub killCurrentExcel (ByVal oexcel As Object)
        Dim proc As System.Diagnostics.Process
        Dim intPID As Integer
        Dim intResult As Integer
        Dim iHandle As IntPtr
        Dim strVer As String

        strVer = oexcel.Version
        iHandle = IntPtr.Zero
        If CInt(strVer) > 9 Then
            iHandle = New IntPtr(CType(oexcel.Parent.Hwnd, Integer))
        Else
            iHandle = FindWindow(Nothing, oexcel.Caption)
        End If
        oexcel.Workbooks.Close()
        oexcel.Quit()
        Marshal.ReleaseComObject(oexcel)
        oexcel = Nothing
        intResult = GetWindowThreadProcessId(iHandle, intPID)
        proc = System.Diagnostics.Process.GetProcessById(intPID)
        proc.Kill()
      End Sub

   in module declare 2 Win32 API :
       Public Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hWnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
    Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    

works great :D
   

Post a Comment

Harap gunakan bahasa yang baik dan sopan, terima kasih