0

是否可以拦截 WM_ENDSESSION 消息以防止另一个应用程序接收它?

我想命令该应用程序在 Windows 重新启动或关闭之前执行附加操作,并且无法以这种方式配置应用程序。

该应用程序是屏幕录像软件,它只是在 Windows 关闭时丢弃视频。我需要防止这种情况并保存视频。

4

1 回答 1

2

是否可以拦截 WM_ENDSESSION 消息以防止另一个应用程序接收它?

从技术上讲是的,使用来自SetWindowsHookEx(). 根据所使用的钩子,您有时可以修改(而不是丢弃)消息,使其看起来像另一条消息,例如WM_NULL. 但是,在 的情况下WM_ENDSESSION,它只是一个通知,而不是一个请求,因此无论应用程序对该消息做什么,Windows 仍然会继续关闭。

我想命令该应用程序在 Windows 重新启动或关闭之前执行附加操作,并且无法以这种方式配置应用程序。

该应用程序是屏幕录像软件,它只是在 Windows 关闭时丢弃视频。我需要防止这种情况并保存视频。

因此,您实际上并不想避免WM_ENDSESSION,您只想延迟其他应用程序处理它,直到您首先执行操作之后。

最好的选择是简单地联系录像机作者并请求添加一项功能以在系统关闭时保存视频。

除此之外,MSDN 还说:

Windows Vista 中的应用程序关闭更改

默认情况下,没有任何可见顶级窗口的应用程序将有 5 秒的时间来处理 WM_ENDSESSION,然后才会终止。

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

这样,Windows 会将您的应用程序视为具有可见的顶级窗口,并将给它 30 秒的时间来处理 WM_ENDSESSION。

因此,您可以尝试使用消息挂钩来拦截WM_QUERYENDSESSION并让它ShutdownBlockReasonCreate()立即调用并返回,然后拦截WM_ENDSESSION以调用视频保存操作并ShutdownBlockReasonDestroy()在完成时调用。当然,假设录像机将视频扔掉以回应WM_ENDSESSION而不是WM_QUERYENDSESSION.

有关 Windows 如何处理这两条消息的详细信息,请参阅 MSDN:

Windows Vista 的关机更改

于 2016-02-05T20:33:14.103 回答