Why is killing the Excel process a bad thing?

跟風遠走 提交于 2019-12-30 23:23:42

问题


I've seen a lot of articles and questions about how to be sure that Excel actually quits when you want it to and the process doesn't stay alive. Here is a knowledge Base article describing the problem and Microsoft's recommended solution. Essentially:

'close files

'Quit Excel
xlApp.quit()

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

Many people don't recommend killing the process; See How to properly clean up Excel interop objects and Understanding Garbage Collection in .net

On the other hand many people don't recommend using GC.Collect. See What's so wrong about using GC.Collect()?

In my experience killing the process is the fastest and easiest way to be sure that Excel is gone. My code kills only the exact process that it starts, no other. I make sure to Close any open workbooks, Quit the application and Release the xlApp object. Finally I check to see if the process is still alive and if so then kill it.

<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

I've seen a lot of people say that killing the process is bad, but I haven't seen any qualitative answers on why. Especially after making sure that files are closed, Excel has quit and we'll only kill the exact process that we started. My question is what are the potential problems with killing the Excel process. Does it hurt perfomance? Will it harm Excel?

Many will also say that with good coding I don't have to kill the process. Maybe, but that doesn't answer the question of "Why is it bad to kill the process?" After closing the files, quitting Excel and releasing the objects; why would it be a bad thing to just make absolutely sure the process is gone?

Edit: Also what is actually left after Excel quits? If Excel was visible, it appears to quit normally, disappearing from view and from the taskbar. So did Excel actually quit or didn't it. It seems to me that Excel actually did quit and that we only have an empty process shell running. Can anyone comment on that?

Edit: It is interesting to me to note that GC (aka Garbage Collection) via GC.Collect() GC.WaitForPendingFinalizers() will actually release the process shell that is left behind after Excel quits. Does that support my assumption that the empty process shell really is garbage after all?

Edit: just found an excellent website on the problem: 50 Ways to kill Excel


回答1:


Look, the fact of the matter is, you should always let the app exit normally if at all possible. Killing the app is a last resort. I understand you're convinced that you don't see anything wrong with doing it in this case, and maybe you're correct. Even if there are absolutely no negative affects to your system from killing it, That doesn't change the fact that it's the wrong thing to do. It's like breaking the law because you know you won't get caught, and it's a victimless crime anyways.

There are, however, potential side-effects that you may not realize. For example, when you forcefully terminate an app, the OS may retain crash data for it. Or it may send crash telemetry to Microsoft. You're essentially telling Microsoft that apps are crashing more often then they actually are, causing their crash statistics to be slightly skewed.

Another possible side effect is that registry hives may not unload correctly. You may have seen this error in the event log from time to time. It typically happens when an app is forcefully closed and it did not close the handles to the registry correctly.

Even if none of those things happen, you can't know what a future version of the OS might do. What works today, might not work tomorrow. This is why you should ALWAYS follow the documented API's and guidelines, because they typically will work very hard to support something they've published, but will typically not work very hard to support something they've specifically told you not to do.




回答2:


When you use automation to control an Office application from another application you will occasionally have to kill the Office process like you do to avoid "leaking" invisible Office applications. This is an unfortunate result of how the Office applications tries to act both as an end-user application and also as an automation server.

I resorted to more or less the same solution as you when using Word on the server side (don't ask why). No matter how much effort we put into shutting Word down properly an increasing number of "invisble" Word processes would accumulate on the server. The only good solution was to kill thoses processes that wouldn't terminate after being instructed to quit.

When a Windows process is killed all resources used by the process is cleaned up by the operating system, e.g. files and other operating system handles like registry handles are closed, memory is freed etc. From the operating system point of view nothing is leaked when a process is terminated.

However, the application may create temporary files that it intend to delete during normal shutdown. Over time these orphaned files may use an increasing amount of space on the disk. Also, if the user has other files open in the application these files may be left in an inconsistent state when the process is terminated and unsaved changes may be lost. Basically, what an application that is killed can "leak" is files that it intend to clean up or delete when it shuts down. Another source of "leaks" are resources acquired on the network (e.g. files open on shares). However, when the process is terminated the network handle will eventually become "stale" and reclaimed by the network server.

Also, I would like to note that Dr. Watson will not collect any crash dump data if a process is killed. This only happens if a process crashes unexpectedly (e.g. has an unhandled exception).

The bottom line: If you are careful killing Excel is probably the best way to avoid "leaking" invisble Excel processes over time. The alternative of letting them run using more and more system resources until the system is restarted is not viable. The cost, if any, should be nothing more than some small files left in the temporary folder.


As an alternative to automating Office you can use the Open XML SDK to open and modify Office files. Initially it might be somewhat more complex but you completely avoid spinning up the heavy Office applications in the process.




回答3:


In my experience there are a few things that a program does when it shuts down:

  1. Release all memory references
  2. Delete any temporary or work files
  3. Save any State data

For these reasons, it is critical that you shut down Excel in the manner which the API describes, using app.Quit(). Where this example deviates from the Norm, is that the API does not release all the COM objects. This leads to step 1) being incomplete. There is no way to ensure that the application shuts down effectively in all cases, as you may not always have control over what COM objects are created.

I have found the best way to utilize Excel (among other office programs) is to use the following process:

  1. Get a list of process IDs with the name containing Excel
  2. Open Excel
  3. Repeat Step 1. Use this to determine the process ID of the new Excel instance you created
  4. Use Excel
  5. Quit Excel, releasing all objects you created and terminating with Application.Quit()
  6. Kill the process

This gives Excel the opportunity to release any objects, delete any temp files and save any state data before the process is terminated. I generally create a singleton class which is responsible for managing excel instances. It implements IDisposable, and on Disposal, it will quit all remaining Excel applications.



来源:https://stackoverflow.com/questions/17781708/why-is-killing-the-excel-process-a-bad-thing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!