关闭应用程序和从任务管理器结束进程有什么区别?

7
使用关闭按钮和从任务管理器结束进程有什么区别?
我知道使用关闭按钮会在消息队列中发布一个WM_CLOSE消息,但我不知道当我们从任务管理器(或类似的应用程序如Killbox或Process Explorer)结束进程时会发生什么。

1
通常情况下,你杀死的是一个进程而不是一个应用程序。 - Basile Starynkevitch
3个回答

7
当您单击应用程序窗口标题栏中的“X”按钮时,这将向窗口发送WM_CLOSE消息。这是一种“优雅”的关闭方式 - 应用程序处理消息,处理任何必要的清理任务,并且如果希望不关闭(通过响应消息返回零)甚至可以拒绝关闭。 WM_CLOSE只是一个请求,窗口或应用程序终止;窗口直到应用程序本身调用DestroyWindow函数才会被销毁。
当您在任务管理器中按下“结束任务”按钮时,Windows首先尝试向应用程序(如果它是GUI应用程序)发送 WM_CLOSE 消息。换句话说,它首先礼貌地询问并给予应用程序终止自身的机会。* 如果您未能在响应最初的WM_CLOSE消息时关闭,任务管理器将通过调用TerminateProcess函数进行跟进。该函数有点不同,因为它强制性地终止应用程序的进程和所有线程,而不需要从应用程序请求许可。这是一种非常严厉的关闭方法,应作为最后的手段使用——例如当应用程序挂起并且不再响应消息时。

TerminateProcess是一个非常低级别的函数,它基本上从内存中剥离了进程的用户模式部分,强制终止它的运行。调用TerminateProcess会绕过关闭通知和DLL_PROCESS_DETACH等细节。您的应用程序无法拒绝关闭,并且没有办法捕获/陷阱/钩子调用TerminateProcess。进程中的所有用户模式代码都将永久停止运行。这是一种非常不干净的关闭过程,有点类似于突然拔掉计算机电源插头。

* 请注意,仅当您使用任务管理器的“应用程序”选项卡来终止应用程序时,此内容才正确。如果您使用“进程”选项卡,则会跳过此步骤并立即调用TerminateProcess函数。这种区别反映在相应按钮的标题中。对于“应用程序”选项卡,按钮标签为“结束任务”; 对于“进程”选项卡,按钮标签为“结束进程”。


我正在尝试使用CreateProcess创建另一个实例(分离进程)来处理WM_CLOSE消息,以便程序重新启动自己,但似乎并没有发生... - user1232138
@user 这与你在这里提出的问题有什么关系?并且你的评论中没有足够的信息来调试这个问题。你有什么代码?当你说“似乎没有发生”时,你是什么意思?相反会发生什么? - Cody Gray
你说过:“你的应用程序没有拒绝关闭的能力,也没有办法捕获/钩取 TerminateProcess 的调用”,但是如果我们不为我们的程序设置 PROCESS_TERMINATE 访问权限呢?使用 TerminateProcess 仍然可以终止我们的程序吗? - user1232138
@user 是的,可能是权限问题。您可以始终使用组策略防止用户关闭应用程序。但是一旦用户提升权限并以管理员身份运行任务管理器,他们可以随心所欲地操作。 - Cody Gray
@Harry:好的发现。确实如此;它实际上是异步的,启动终止并立即返回。但那根本不需要在那里。 - Cody Gray
显示剩余2条评论

4
使用 WM_CLOSE 来结束进程只是向该进程发送信号消息,让目标进程处理该消息并平稳退出。或者,该进程在其 WM_CLOSE 处理程序中选择不退出。
通过任务管理器终止进程将使用强制终止的 TerminateProcess 方法:

TerminateProcess 函数用于无条件地导致进程退出。如果使用 TerminateProcess 而不是 ExitProcess,则可能会影响由动态链接库 (DLL) 维护的全局数据状态。

此函数停止进程内的所有线程的执行,并请求取消所有未决的 I/O 操作。终止的进程在所有未决 I/O 完成或已取消之前不能退出。当进程终止时,它的内核对象不会被销毁,直到拥有该进程打开句柄的所有进程都释放了这些句柄。

TerminateProcess 是异步的;它启动终止操作并立即返回。如果需要确保进程已终止,请使用该进程的句柄调用 WaitForSingleObject 函数。进程无法防止自身被终止。


3

如果您使用关闭按钮关闭应用程序,则可以让应用程序执行必要的关闭任务(如果有)。如果您从任务管理器中终止进程,则应用程序没有机会执行这些任务,而是在不通知的情况下终止应用程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接