Excel过程仍然在VB.net关闭后运行

我的问题基本上就是如何结束使用Excel时运行的Excel.exe进程。 在应用程序中,我打开并使用一对Excel工作簿,然后让用户按照自己的意愿去做,但问题是我的应用程序从未放弃过程。

如果应用程序在关闭excel之前关闭,则在excel关闭时结束该过程,否则如果在关闭excel后关闭应用程序,则该过程将保持运行。

我已经尝试了一些我在互联网上发现的与GC.collect有关的事情,并等待未决的终结器或者沿着这些线路发生的事情,但是都没有成功。

我也可以愉快地关闭Excel过程,唯一的问题是不知道我是否关闭了一个用户重要的电子表格,他们忽略了存储还是我的存储。

我不确定我的任何代码是否有助于解答,但我正在使用microsoft.office.interop.excel来获取excel,并且我正在使用已保存在应用程序资源文件夹中的工作簿。

-编辑-

这是我试过的一切,我知道这有点矫枉过正,但遗憾的是它仍然不能结束这个过程

Marshal.ReleaseComObject(FirstWorksheet)
Marshal.FinalReleaseComObject(FirstWorksheet)
Marshal.ReleaseComObject(SecondWorksheet)
Marshal.FinalReleaseComObject(SecondWorksheet)
Marshal.ReleaseComObject(ThirdWorksheet)
Marshal.FinalReleaseComObject(ThirdWorksheet)
Marshal.ReleaseComObject(FourthWorkSheet)
Marshal.FinalReleaseComObject(FourthWorkSheet)
Marshal.ReleaseComObject(xlRange)
Marshal.FinalReleaseComObject(xlRange)
Marshal.ReleaseComObject(SecondxlRange)
Marshal.FinalReleaseComObject(SecondxlRange)
Marshal.ReleaseComObject(thirdxlRange)
Marshal.FinalReleaseComObject(thirdxlRange)
Marshal.ReleaseComObject(fourthxlRange)
Marshal.FinalReleaseComObject(fourthxlRange)
Marshal.ReleaseComObject(.activeworkbook)
Marshal.FinalReleaseComObject(.activeworkbook)
Marshal.ReleaseComObject(excelApplication)
Marshal.FinalReleaseComObject(excelApplication)
MSExcelControl.QuitExcel() 'A function made by someone else I work with that was meant to close excel's process
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()

- 编辑 - 这是quitExcel方法

Friend Shared Sub QuitExcel()
    If Not getExcelProcessID = -1 Then
        If Not excelApp Is Nothing Then
            'Close and quit
            With excelApp
                Try
                    Do Until .Workbooks.Count = 0
                        'Close all open documents without saving
                        .Workbooks(1).Close(SaveChanges:=0)
                    Loop
                Catch exExcel As Exception
                    'Do nothing
                End Try
                Try
                    .ActiveWorkbook.Close(SaveChanges:=0)
                Catch ex As Exception
                    'Do nothing
                End Try

                Try
                    .Quit()
                Catch ex As Exception
                    'Do nothing
                Finally
                    myExcelProcessID = -1
                End Try
            End With
            excelApp = Nothing
        End If
    End If
End Sub

他已经尝试在他的课程中使用进程ID做同样的事情,问题在于他没有工作,这就是为什么我试图再次获得进程ID的原因


好的解决方案Alex,我们不应该这样做,但我们做到了,EXCEL不会结束。 我采取了你的解决方案,并创建了下面的代码,在我的应用程序导入或导出Excel之前,我打电话给ExcelProcessInit,然后在ExcelProcessKill完成后调用它。

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

这需要很长时间,但我终于解决了,最好的方法是在创建excel应用程序时记录进程ID,这意味着您只知道与进程相关的唯一ID。

为此,我查看了已经存在的所有进程,并在ID数组中记录了excel进程的ID

            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

然后在打开矿后直接重复这个过程(试图阻止他们自己打开excel并拥有2个新的excel进程)记录新的ID,检查不在最后一个列表中的ID并将其存储为整数。

然后,您最后需要做的就是遍历流程列表并使用您的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

我知道这是一个古老的线程,但如果有人回来,你实际上必须调用你在工作簿中触及的每个Interop.Excel对象。 如果你将一个实例化的类从Excel中拖入你的代码中,那么当你完成它时,Marshal.ReleaseComObject。 甚至每个细胞。 这很疯狂,但这是我能够解决相同问题的唯一方法。

并确保你没有致命的异常,并留下未发布的东西... Excel将保持开放。

Excel.Applicaiton? Marshal.ReleaseComObject的。

Excel.Workbook? Marshal.ReleaseComObject的。

Excel.Workshet? Marshal.ReleaseComObject的。

Excell.Range? Marshal.ReleaseComObject的。

通过行循环? Marshal.ReleaseComObject你循环的每一行和单元格。

Exce.Style? Marshal.ReleaseComObject ...至少这是我必须做的......

如果您计划使用PIA访问Excel,请从您编写的第一行代码中计划如何发布对象。 我所拥有的最佳方法是确保从Excel对象中提取excel值并将其加载到我自己的内部变量中。 然后立刻打电话给你访问的Marshal.ReleaseComObject。 通过应用程序,工作簿,工作表,ListObject,表等中的列表循环访问excel对象往往是最难发布的。 因此规划相当关键。

链接地址: http://www.djcxy.com/p/35659.html

上一篇: Excel process still runs after closing in VB.net

下一篇: c# excel does not clean up after creating pdf file