我的问题基本上就是如何结束使用excel时运行的Excel.exe进程。在应用程序中,我打开并使用带有几张纸的excel工作簿,然后将它们留给用户随意使用,我的问题是我的应用程序永远不会放弃Excel流程。
如果在关闭excel之前关闭了应用程序,则关闭excel时进程结束,否则如果在关闭excel后关闭我的应用程序,则该进程将继续运行。
我已经尝试了一些我在互联网上发现的与GC.collect有关的事情,并等待待定的终结器或其他类似的东西但是没有用。
我也可以愉快地关闭excel流程,唯一的问题是我不知道我是否正在关闭他们忽略了或者我已经忽略的用户重要电子表格。
我不确定我的代码是否有任何帮助,但我使用microsoft.office.interop.excel来获取excel,我正在使用已保存在应用程序资源文件夹中的工作簿。< / p>
- 编辑 -
这是我尝试过的一切,我知道这有点矫枉过正但遗憾的是它仍然没有结束这个过程
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()
-Edit-这是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的原因
答案 0 :(得分:8)
好的解决方案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
答案 1 :(得分:4)
这花了很长时间但我终于解决了,最好的方法是在创建excel应用程序时记录进程ID,这意味着您只知道与进程关联的唯一ID。 / p>
为此,我查看了已经存在的所有进程,在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
答案 2 :(得分:4)
我知道这是一个旧线程,但是如果有人回到这个,你实际上必须调用你在工作簿中触摸的每个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对象往往是最难发布的。因此,规划是非常关键的。
答案 3 :(得分:3)
前一段时间我遇到了同样的问题,请尝试在excel对象上使用Marshal.ReleaseComObject。它位于System.Runtime.InteropServices命名空间中。还记得事先关闭你的excel对象。
xlWorkbook.Close();
xlApp.Close();
Marshal.ReleaseComObject(xlWorkbook);
Marshal.ReleaseComObject(xlApp);