用休眠替换shutdown

时间:2011-01-12 09:58:14

标签: windows winapi shutdown

Tl; dr :是否有可能在处理之前捕获系统关闭消息(以及更改/删除它们)?


初步

我正在开发一个集群管理软件。目前,群集中的闲置计算机正被第三方软件关闭。在我的软件测试环境中,在关闭,启动和启动所有程序时浪费大量时间是不可接受的。结果,机器被认为空闲的点已被设置为3小时。这不是“省电” 我们的想法是用休眠消息替换系统关闭消息。 操作系统是Windows XP,但计划更新 Windows 7 。理想情况下,解决方案应该适用于两者。

到目前为止的想法

  • 替换shutdown.exe
    这就是我用UNIX客户端做到的。但是,我不认为常见的Windows应用程序只是在exec()上调用shutdown.exe来关闭系统。相反,他们可能会拨打ExitWindowsEx()。我想抓住这次电话会产生的信息。

  • 处理WM_QUERYENDSESSION
    这也不是解决方案,原因有两个:

    • 此消息以不可预测的顺序传递给所有正在运行的程序。即使我通过返回FALSE来取消关闭,某些程序可能已经提前收到了消息并已经退出。
    • 自Vista以来,返回FALSE不会导致关闭的静默取消。相反,整个屏幕被阻止,并且用户被告知阻止关闭的程序。因此,即使我在此时设法进入休眠状态,在下次启动时整个屏幕也会被阻止。

    特别是第一点至关重要。如果不花费宝贵的时间,我只能证明关闭机器是正确的。从休眠状态返回时不必重新启动程序是其中很重要的一部分。

  • SetWindowsHookEx()
    我想到了钩子。但是,这个方法看起来很痛苦,因为this MSDN article指出,我必须同时提供我的程序和包含两种风格的钩子的DLL(x86_64和x86)。这肯定会失败 但是我们假设我设法让它工作,我似乎无法捕获系统的关闭消息之前它被分派到其他窗口,更不用说改变或删除该消息了。

限制

基本上没有限制。由于我自己安装在这些机器上运行的Windows,所以一切顺利。如果一个手工制作的鼠标驱动程序,模拟鼠标移动点击“确定,不要关机”按钮是解决方案,所以就这样(另一个指标,我不是想做邪恶 ;) )。解决方案越普遍(例如能够拦截和改变任何消息),就越好!

任何提示和链接(未经测试的,实验性的东西)都表示赞赏。

1 个答案:

答案 0 :(得分:0)

这是您需要执行的操作以防止关机

  1. 编写一个DLL,该DLL捕获并重定向ExitWindowsEx()函数。您可以使用Microsoft Detours Library完成此操作。在测试过程中测试此dll。

  2. 测试完dll后,默认情况下使用AppInit_Dlls注册表值将该DLL加载到每个进程中,或者使用detours软件包提供的实用程序有选择地将DLL加载到所需的任何进程中。 / p>

  3. 编写一个进程,该进程使用IPC机制之一与所有进程中加载​​的DLL进行通信,以允许/拒绝/重定向关闭。