【发布时间】:2013-07-22 07:03:21
【问题描述】:
我看过很多关于如何确保 Excel 在您想要的时候真正退出并且进程不会继续存在的文章和问题。 Here is a knowledge Base article 描述问题和微软推荐的解决方案。本质上:
'close files
'Quit Excel
xlApp.quit()
'Release and collect garbage
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlApp)
GC.Collect()
GC.WaitForPendingFinalizers()
很多人不建议杀掉进程;看 How to properly clean up Excel interop objects 和Understanding Garbage Collection in .net
另一方面,很多人不推荐使用 GC.Collect。见What's so wrong about using GC.Collect()?
根据我的经验,终止进程是确保 Excel 消失的最快和最简单的方法。我的代码只杀死它启动的确切进程,没有其他。我确保关闭所有打开的工作簿,退出应用程序并释放 xlApp 对象。最后我检查进程是否还活着,如果还活着,就杀死它。
<System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, _
ByRef lpdwProcessId As Integer) As Integer
End Function
Sub testKill()
'start the application
Dim xlApp As Object = CreateObject("Excel.Application")
'do some work with Excel
'close any open files
'get the window handle
Dim xlHWND As Integer = xlApp.hwnd
'this will have the process ID after call to GetWindowThreadProcessId
Dim ProcIdXL As Integer = 0
'get the process ID
GetWindowThreadProcessId(xlHWND, ProcIdXL)
'get the process
Dim xproc As Process = Process.GetProcessById(ProcIdXL)
'Quit Excel
xlApp.quit()
'Release
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlApp)
'set to nothing
xlApp = Nothing
'kill the process if still running
If Not xproc.HasExited Then
xproc.Kill()
End If
End Sub
我看到很多人说杀死进程是不好的,但我还没有看到任何关于原因的定性答案。特别是在确保文件已关闭之后,Excel 已退出,我们只会终止我们开始的确切进程。我的问题是杀死 Excel 进程的潜在问题是什么。会影响性能吗?它会损害 Excel 吗?
许多人还会说,通过良好的编码,我不必终止进程。也许吧,但这并不能回答“为什么终止进程不好?”的问题。关闭文件后,退出 Excel 并释放对象;为什么绝对确定该过程已经消失会是一件坏事?
编辑:Excel 退出后还剩下什么?如果 Excel 可见,它似乎正常退出,从视图和任务栏中消失。 Excel实际上退出了还是没有退出。在我看来,Excel 实际上确实退出了,而且我们只有一个空的进程 shell 正在运行。任何人都可以对此发表评论吗?
编辑:有趣的是我注意到 GC(又名垃圾收集)通过 GC.Collect() GC.WaitForPendingFinalizers() 实际上会释放 Excel 退出后留下的进程外壳。这是否支持我的假设,即空进程外壳毕竟真的是垃圾?
编辑:刚刚找到一个关于这个问题的优秀网站:50 Ways to kill Excel
【问题讨论】:
-
杀死一个进程就像从墙上猛拉电源线来关闭您的计算机。当然,它有效,但它不是关闭程序的正确方法。
-
@CodyGray 现代机器的设计目的是从电源线抽出中恢复得相当好。如果你还没有保存它,你只会丢失一些东西。我猜他想知道现代 Excel 是否同样适用?
-
@Toby 我不同意。是的,已经做了一些工作来防止事情像过去那样出错,但这并不意味着它是关闭系统的有效方法。安全工程师在汽车上工作,以确保您在发生事故时也不会死亡,但这并不意味着您不需要安全驾驶。所以是的,Windows 通常会在进程终止后进行清理,但这并不是正确的做法。
-
@DavidColwell 我已经编写了许多使用 Excel 执行某些重要工作的应用程序,并且在 Excel 中执行某些操作后遇到了许多 Excel 进程未关闭的问题。
-
我发现摆脱 excel.exe 需要三件事:将对 excel 应用程序的所有引用设置为 null/nothing、
GC.Collect()、和应用程序必须具有被用户或通过调用Quit关闭,如果用户取消了不计入的关闭。当我做这一切时,我只会在调试时得到额外的 excel.exes(因为停止执行不会清理。)
标签: c# .net vb.net excel excel-interop