Excel process still runs after closing in VB.net

前端 未结 4 574
孤城傲影
孤城傲影 2020-12-19 16:43

My question is basically just how to end the Excel.exe process that runs when using excel. In the application I open and use an excel workbook with a couple sheets, then lea

相关标签:
4条回答
  • 2020-12-19 17:20

    Good solution Alex, we shouldn't have to do this, but we do, EXCEL just won't end. I took your solution and created the code below, I call ExcelProcessInit before my app imports or exports with Excel, then call ExcelProcessKill after it's complete.

    Private mExcelProcesses() As Process
    
    Private Sub ExcelProcessInit()
      Try
        'Get all currently running process Ids for Excel applications
        mExcelProcesses = Process.GetProcessesByName("Excel")
      Catch ex As Exception
      End Try
    End Sub
    
    Private Sub ExcelProcessKill()
      Dim oProcesses() As Process
      Dim bFound As Boolean
    
      Try
        'Get all currently running process Ids for Excel applications
        oProcesses = Process.GetProcessesByName("Excel")
    
        If oProcesses.Length > 0 Then
          For i As Integer = 0 To oProcesses.Length - 1
            bFound = False
    
            For j As Integer = 0 To mExcelProcesses.Length - 1
              If oProcesses(i).Id = mExcelProcesses(j).Id Then
                bFound = True
                Exit For
              End If
            Next
    
            If Not bFound Then
              oProcesses(i).Kill()
            End If
          Next
        End If
      Catch ex As Exception
      End Try
    End Sub
    
    Private Sub MyFunction()
      ExcelProcessInit()
      ExportExcelData() 'Whatever code you write for this...
      ExcelProcesKill()
    End Sub
    
    0 讨论(0)
  • 2020-12-19 17:24

    I know this is an old thread, but if anyone comes back to this, you actually have to call every Interop.Excel object you touch in the workbook. If you pull in an instantiated class from Excel into your code, when you're done with it, Marshal.ReleaseComObject. Even every cell. It's crazy, but it's the only way I was able to get the same issue resolved.

    And make darn sure you don't have a fatal exception and leave something unreleased... Excel will stay open.

    Excel.Applicaiton? Marshal.ReleaseComObject.

    Excel.Workbook? Marshal.ReleaseComObject.

    Excel.Workshet? Marshal.ReleaseComObject.

    Excell.Range? Marshal.ReleaseComObject.

    Looping through Rows? Marshal.ReleaseComObject every row and cell you loop through.

    Exce.Style? Marshal.ReleaseComObject... At least this is what I had to do...

    If you plan on using the PIA to access Excel, from the first line of code you write, plan how you're going to release your objects. The best approach I've had is to make sure that I pull an excel value out of the Excel object and load it into my own internal variable. Then imediately call Marshal.ReleaseComObject you accessed. Looping through excel objects via a list in a Application, Workbook, Sheet, ListObject, Table, etc, tends to be the hardest to release. Hence planning is rather critical.

    0 讨论(0)
  • 2020-12-19 17:27

    It's taken a long time but I've finally solved it, the best way to do it is to record the process ID when you create the excel application, this means that you know the unique ID associated with your process only.

    To do this, I looked at all the processes that were already there, recording the excel processes' IDs in an array of IDs

                msExcelProcesses = Process.GetProcessesByName("Excel")
                'Get all currently running process Ids for Excel applications
                If msExcelProcesses.Length > 0 Then
                    For i As Integer = 0 To msExcelProcesses.Length - 1
                        ReDim Preserve processIds(i)
                        processIds(i) = msExcelProcesses(i).Id
                    Next
                End If
    

    Then repeat the process straight after opening mine (to try and prevent them opening excel themselves and having 2 new excel processes) record the new IDs, check for an ID that wasn't in the last list and store it as an integer.

    Then all you need to do at the end is iterate through the list of processes and kill the one with your ID

                    Dim obj1(1) As Process
                    obj1 = Process.GetProcessesByName("EXCEL")
                    For Each p As Process In obj1
                        If p.Id = MSExcelControl.getExcelProcessID Then
                            p.Kill()
                        End If
                    Next
    
    0 讨论(0)
  • 2020-12-19 17:45

    I had the same problem a while ago, try using Marshal.ReleaseComObject on your excel objects. It's located ed in the System.Runtime.InteropServices namespace. Also remember to close down your excel objects beforehand.

    xlWorkbook.Close();
    xlApp.Close();
    Marshal.ReleaseComObject(xlWorkbook);
    Marshal.ReleaseComObject(xlApp);
    
    0 讨论(0)
提交回复
热议问题