如果系统正在尝试关闭,则应用可以通过覆盖OnQueryEndSession()
并返回FALSE
来阻止此关闭。当然,这意味着WM_ENDSESSION
是关于关闭的唯一权威消息。
另一方面,this question的最佳答案不亚于Raymond Chen所说,回复WM_ENDSESSION
基本上毫无意义。所以这很令人困惑。
是否有某种“最佳实践”原则适用于决定哪些消息(如果有的话)应该响应以执行哪种应用程序关闭工作?
特别是,如果没有处理任何消息,关闭过程是否会导致应用程序关闭,就像用户手动关闭应用程序一样(例如,单击红色X关闭按钮)?
答案 0 :(得分:4)
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 到消息循环,除非我自己做的。)