And*_*son 15 c++ api winapi shutdown restart
我知道当Windows关闭时,它会向每个应用程序发送WM_QUERYENDSESSION消息.这样可以轻松检测Windows何时关闭.但是,是否可以知道计算机是否要关闭电源,或者是否在Windows关闭后重新启动.
我并不是特别有希望,考虑到MSDN上的文档有这样的说法WM_QUERYENDSESSION:"......无法确定发生了哪个事件,"但stackoverflow的累积聪明从未让我感到惊讶.
小智 8
在Windows 7(可能还有Vista/8/Server)中,您可以使用系统事件来跟踪Windows是否正在关闭(以及关闭计算机电源)或只是重新启动.每次启动关闭/重启(无论如何 - 单击"开始"菜单中的按钮或以编程方式),Windows 7都会在系统日志中写入一个或两个事件,源USER32,事件ID 1074.您可以看到这些事件已记录,如果从管理工具打开事件查看器(筛选系统日志以仅查看ID 1074).这些事件的描述(消息)包含关闭类型.因此,您可以解析此类型的最新事件的描述(在启动关闭之后),查找必要的字(关闭,重新启动/重新启动).
我没有尝试在使用电源按钮正常关闭Windows时看到事件中写入的关闭类型(我通常禁用此功能),但有些网站建议它声明"断电"类型而不是"关闭" - 如果你需要确定的话,请查看.或者只是寻找"重启"类型 - 如果找不到,则假定为"关闭"类型.
在Windows XP中,根据我的经验,只有在以编程方式完成关闭/重启时才会记录事件1074(例如,在程序安装期间或使用shutdown.exe实用程序).因此它不会注册从shell(Explorer)启动的关闭,但是也许您可以将此方法与从另一个答案中建议的读取注册表中的值结合使用.另外,请记住,在WinXP中,事件1074的消息包含"重启"一词,无论真正的关闭类型是什么,因此您应该查看"关闭类型:"字段,该字段将指示"关闭"或"重启".
与此相关,只要Windows由于某种原因无法关闭/重启(例如,如果应用程序不允许关闭作为对WM_QUERYENDSESSION的响应),则会记录事件ID 1073.在这种情况下,该消息还将在WinXP中包含"关闭","重启"或"关闭电源"等字样.对于Win7,这种类型的事件在我们的情况下不太有用,因为它在关闭和重新启动之间不会有任何区别.但是对于WinXP - 如果你只需要拦截关机/重启,执行一些操作,然后继续相应的关机或重启过程 - 它应该按预期工作.
通常可行的技巧是捕获WM_ENDSESSION并记录它.现在跟踪时间.如果系统恢复到合理的范围内(比如5分钟).那是重启,而不是关机.
想法:如果系统在5分钟内重新启动,用户点击"关机"或"重启"是否真的重要?
如果你真的需要检测关闭(和唯一的原因,我认为你需要做的是,如果你根据停机之间VS重启一个不起眼的行为差异的软件),你可以调查API hooking的ExitWindowsEx和相关的功能,但我不推荐这种方法.重新思考,如果你真的需要直接检测到这一点.