为什么要杀死Excel进程是一件坏事?

我已经看到很多关于如何确保Excel实际上在您需要时退出并且该过程不会保持活跃状态​​的文章和问题。 以下是描述问题的知识库文章和Microsoft推荐的解决方案。 主要有:

'close files

'Quit Excel
xlApp.quit()

'Release and collect garbage
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlApp)
GC.Collect()
GC.WaitForPendingFinalizers()

许多人不建议杀死这个过程; 请参阅如何正确清理Excel互操作对象和了解.net中的垃圾收集

另一方面,很多人不推荐使用GC.Collect。 看看使用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退出后留下的进程外壳。 这是否支持我的假设,即空的流程外壳真的是垃圾?

编辑:刚刚发现一个优秀的网站上的问题:杀死Excel的50种方法


看,问题的实质是,如果可能的话,你应该始终让应用程序正常退出。 杀死该应用程序是最后的手段。 我知道你确信在这种情况下你没有看到有什么问题,也许你是对的。 即使对你的系统没有任何负面影响,也不会改变这是一件错误的事情。 这就像违反法律,因为你知道你不会被抓到,而且这无疑是一个无害的犯罪。

但是,您可能没有意识到潜在的副作用。 例如,当您强制终止应用程序时,操作系统可能会为其保留崩溃数据。 或者它可能会向Microsoft发送崩溃遥测。 实质上,你告诉微软应用程序正在崩溃,导致它们的崩溃统计信息略有偏差。

另一个可能的副作用是注册表配置单元可能无法正确卸载。 您可能会不时在事件日志中看到此错误。 它通常发生在应用程序被强制关闭并且没有正确关闭注册表的句柄时。

即使没有这些事情发生,你也不知道未来版本的操作系统可能会做什么。 今天有效,明天可能无法运作。 这就是为什么你应该始终遵循已记录的API和准则,因为他们通常会非常努力地支持他们发布的内容,但通常不会很努力地支持他们明确告诉你不要做的事情。


当您使用自动化从另一个应用程序控制Office应用程序时,您偶尔必须像执行操作一样杀死Office进程,以避免“泄漏”不可见的Office应用程序。 这是Office应用程序试图既作为最终用户应用程序又作为自动化服务器的不幸结果。

我在服务器端使用Word时或多或少使用了与您相同的解决方案(请不要问为什么)。 无论我们付出多少努力来正确关闭Word,越来越多的“无形”Word处理将累积在服务器上。 唯一好的解决方案是杀死那些在被指示退出后不会终止的进程。

当Windows进程被终止时,进程使用的所有资源都被操作系统清除,例如文件和注册表句柄等其他操作系统句柄被关闭,内存被释放等等。从操作系统的角度来看,当过程终止。

但是,应用程序可能会在正常关机期间创建它打算删除的临时文件。 随着时间的推移,这些孤立文件可能会在磁盘上占用越来越多的空间。 另外,如果用户在应用程序中打开其他文件,则当进程终止并且未保存的更改可能丢失时,这些文件可能会处于不一致状态。 基本上,被杀的应用程序可以“泄漏”的是它打算在关闭时清除或删除的文件。 “泄漏”的另一个来源是在网络上获取的资源(例如,在共享上打开的文件)。 但是,当进程终止时,网络句柄将最终变为“陈旧”并由网络服务器回收。

另外,我想指出,如果一个进程被杀死,Dr.Watson不会收集任何崩溃转储数据。 只有当进程意外崩溃时(例如,有未处理的异常),才会发生这种情况。

底线:如果你仔细查杀Excel,可能是避免随时间流逝“泄漏”无形Excel程序的最佳方法。 在系统重新启动之前让它们使用越来越多的系统资源来运行的替代方案是不可行的。 成本(如果有的话)应该只是临时文件夹中剩余的一些小文件。


作为Office自动化的替代方案,您可以使用Open XML SDK打开和修改Office文件。 最初它可能稍微复杂一些,但是您完全可以避免在这个过程中使用繁重的Office应用程序。


根据我的经验,程序在关闭时会执行一些操作:

  • 释放所有内存引用
  • 删除任何临时或工作文件
  • 保存任何状态数据
  • 由于这些原因,使用app.Quit()以API描述的方式关闭Excel是至关重要的 。 在这个例子偏离Norm的地方,是API不会释放所有的COM对象。 这导致步骤1)不完整。 在任何情况下都无法确保应用程序有效关闭,因为您可能无法始终控制创建哪些COM对象。

    我发现使用Excel(其他办公软件)的最佳方式是使用以下过程:

  • 获取包含Excel名称的进程ID列表
  • 打开Excel
  • 重复步骤1.使用它来确定您创建的新Excel实例的进程ID
  • 使用Excel
  • 退出Excel,释放您创建并以Application.Quit()结束的所有对象
  • 杀死这个过程
  • 这使Excel有机会释放任何对象,删除任何临时文件并在过程终止之前保存任何状态数据。 我通常创建一个负责管理Excel实例的单例类。 它实现了IDisposable,并且在处置时,它将退出所有剩余的Excel应用程序。

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

    上一篇: Why is killing the Excel process a bad thing?

    下一篇: How to properly clean up interop objects in C#