我应该同时处理WM_ENDSESSION,WM_QUERYENDSESSION吗?

时间:2015-07-13 01:39:20

标签: windows shutdown

如果系统正在尝试关闭,则应用可以通过覆盖OnQueryEndSession()并返回FALSE来阻止此关闭。当然,这意味着WM_ENDSESSION是关于关闭的唯一权威消息。

另一方面,this question的最佳答案不亚于Raymond Chen所说,回复WM_ENDSESSION基本上毫无意义。所以这很令人困惑。

是否有某种“最佳实践”原则适用于决定哪些消息(如果有的话)应该响应以执行哪种应用程序关闭工作?

特别是,如果没有处理任何消息,关闭过程是否会导致应用程序关闭,就像用户手动关闭应用程序一样(例如,单击红色X关闭按钮)?

2 个答案:

答案 0 :(得分:4)

来自Microsoft的

This article对Vista之前和之后的会话结束最佳实践进行了非常全面的讨论。文章清楚地表明,如果一个人收到WM_QUERYENDSESSION,那么就会在某个时候关闭。

一旦所有应用程序都响应WM_ENDSESSION消息,或者在收到WM_ENDSESSION消息后5秒内被迫终止,Windows可能会随时关闭。这可能会限制响应WM_ENDSESSION可以采取的措施。

如果申请需要更多时间来清理自己:

  

如果您的应用程序响应WM_ENDSESSION可能需要5秒以上的时间来完成其关闭处理,它应该在其WM_QUERYENDSESSION处理程序中调用ShutdownBlockReasonCreate(),并立即响应TR_ WM_QUERYENDSESSION,以免阻止关闭。然后它应该在其WM_ENDSESSION处理程序中执行所有关闭处理。

Windows显然不会向您的应用程序发送任何其他消息,以允许它退出"优雅地" (例如WM_CLOSE)。相反,它只会调用TerminateProcess。如果你想要一个优雅的关闭,你必须在上述限制内自己构建它。

答案 1 :(得分:1)

确实需要在 WM_ENDSESSION 中关闭您的应用程序,至少如果您想支持 Restart Manager API。我认为 MSDN 和 Raymond 在这里都错了。 (也许它最近发生了变化,或者他们忽略了重启管理器?)

安装程序使用重新启动管理器 API 来关闭和重新启动已锁定需要替换的文件的 exe。为了支持被它重启,你调用RegisterApplicationRestart,然后需要有一个处理WM_QUERYENDSESSION和WM_ENDSESSION的窗口。

如果您没有在 WM_ENDSESSION 处理程序中关闭您的应用程序,它只会继续运行并阻止重新启动管理器,进而阻止安装程序尝试使用它。

我很艰难地发现了这一点。 MSDN 明确表示您不需要调用 PostQuitMessage,但如果我不这样做,那么我的进程将继续运行。

我怀疑文档没有意识到与整个操作系统关闭时发生的情况相比,重新启动管理器是不同的,并且没有那么有力。

(编辑:我应该补充一点,这是一个简单的 ATL COM EXE 服务器,但据我所知,没有什么复杂的事情,而且 Windows 根本没有触发 WM_QUIT 到消息循环,除非我自己做的。)