Excel过程仍然在VB.netclosures后运行

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

如果在closuresexcel之前closures了应用程序,那么在excelclosures的时候这个过程就会结束,否则如果我在closuresexcel之后closures了我的应用程序,那么这个过程将继续运行。

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

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

我不确定是否有任何代码可以帮助我的答案,但我正在使用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 

他已经试着用class里的进程ID做同样的事情,问题是他没有工作,这就是为什么我试图再次获得进程ID,

Alex很好的解决scheme,我们不应该这样做,但是我们呢,EXCEL就是不会结束的。 我采取了您的解决scheme,并创build了下面的代码,在我的应用程序导入或导出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 

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

为此,我查看了已经存在的所有进程,并在ID数组中logging了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进程)logging新的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。 甚至每个细胞。 这很疯狂,但这是我能够解决相同问题的唯一方法。

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

Excel.Applicaiton? Marshal.ReleaseComObject的。

Excel.Workbook? Marshal.ReleaseComObject的。

Excel.Workshet? Marshal.ReleaseComObject的。

Excell.Range? Marshal.ReleaseComObject的。

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

Exce.Style? Marshal.ReleaseComObject …至less这是我所要做的…

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

我刚才也遇到同样的问题,试试在你的excel对象上使用Marshal.ReleaseComObject。 它位于System.Runtime.InteropServices命名空间中。 另外记得事先closures你的excel对象。

 xlWorkbook.Close(); xlApp.Close(); Marshal.ReleaseComObject(xlWorkbook); Marshal.ReleaseComObject(xlApp);