有没有可能订阅一个 Windows 事件,在 Windows 进入或退出睡眠或休眠状态时触发?
我需要让我的应用程序在计算机进入睡眠状态时得到通知以便进行一些清理工作,并避免它从睡眠状态中恢复时出现时间问题。
有没有可能订阅一个 Windows 事件,在 Windows 进入或退出睡眠或休眠状态时触发?
我需要让我的应用程序在计算机进入睡眠状态时得到通知以便进行一些清理工作,并避免它从睡眠状态中恢复时出现时间问题。
ON_MESSAGE()
添加到消息映射中,查找WM_POWERBROADCAST
消息,如下例所示:BEGIN_MESSAGE_MAP(CFrameworkWndDoc, CWindowDocument)
//{{AFX_MSG_MAP(CFrameworkWndDoc)
ON_WM_CHAR()
ON_WM_TIMER()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_POWERBROADCAST, OnPowerMsgRcvd)
END_MESSAGE_MAP()
接下来,您需要添加消息处理程序函数以及类定义更改,以声明消息处理程序的成员函数,以便您可以检查wParam
变量以获取消息类型,如以下框架所示:
// Handle the WM_POWERBROADCAST message to process a message concerning power management
// such as going to Sleep or Waking Up.
LRESULT CFrameworkWndDoc::OnPowerMsgRcvd(WPARAM wParam, LPARAM lParam)
{
switch (wParam) {
case PBT_APMPOWERSTATUSCHANGE:
TRACE0("PBT_APMPOWERSTATUSCHANGE received\n");
break;
case PBT_APMRESUMEAUTOMATIC:
TRACE0("PBT_APMRESUMEAUTOMATIC received\n");
break;
case PBT_APMRESUMESUSPEND:
TRACE0("PBT_APMRESUMESUSPEND received\n");
break;
case PBT_APMSUSPEND:
TRACE0("PBT_APMSUSPEND received\n");
break;
}
return 0;
}
PBT_APMSUSPEND received
PBT_APMRESUMESUSPEND received
PBT_APMRESUMEAUTOMATIC received
Intel的Lynn Merrill所写的《优雅应用程序暂停的艺术》提供了有关处理Windows下与电源管理相关的各种Windows消息类型的信息,但该文档的日期为2005年,因此并非所有材料都适用于Windows XP之后的版本。在描述此文档中的消息序列时,至少有一条不再使用的消息是PBT_APMQUERYSUSPEND
消息,该消息在Windows Vista之后不再被Windows使用,它曾用于请求应用程序是否能够暂停。现在,SetThreadExecutionState()
函数用于指示线程不能被中断以更改为睡眠或休眠状态。有关电源管理状态消息更改的详细信息,请参见stackoverflow上的答案Can't catch sleep suspend messages (winxp)。
自Windows XP以来的系统电源状态事件
自Windows XP以来,Microsoft已经改进了电源管理,因为Windows操作系统的各个版本共享更多的组件,而且现在部署在需要更仔细的电源管理的电池供电的小型设备上。请参见Registering for Power Events。有一个RegisterPowerSettingNotification()
函数和一个UnregisterPowerSettingNotification()
函数。
RegisterPowerSettingNotification
函数注册通知。当相应的电源设置更改时,系统会发送通知,具体如下:
WM_POWERBROADCAST
消息,其中wParam
为PBT_POWERSETTINGCHANGE
,lParam
指向一个POWERBROADCAST_SETTING
结构。RegisterServiceCtrlHandlerEx
函数注册了HandlerEx
回调函数,因此会接收到一次调用。发送到HandlerEx
回调函数的lpEventData
参数指向一个POWERBROADCAST_SETTING
结构。POWERBROADCAST_SETTING
结构中,PowerSetting
成员包含标识通知的GUID,而Data成员包含电源设置的新值。系统电源状态和电池状况
您可以使用Windows系统服务API函数GetSystemPowerStatus()
来检索当前的电源状态。
检索系统的电源状态。该状态指示系统是否正在使用交流或直流电源,电池当前是否正在充电,剩余多少电池寿命以及电池节能模式开启或关闭。
但是请注意,在SYSTEM_POWER_STATUS
结构中返回的信息关于电池状态和交流/直流电源来源,而不是实际设备的电源状态,例如睡眠或休眠。
如果Windows设备处于睡眠或休眠状态,则您的应用程序将无法运行,因此无法使用此函数确定当前的Windows电源状态。我在这里包括这个注意事项,因为它可能对正在研究此主题的人有用。
不确定您需要多频繁地监控此项内容,但如果您在.NET中编写一个服务,可以重写ServiceBase,将CanHandlePowerEvent设置为true,然后通过PowerBroadcastStatus枚举通知您电源变化的情况。
您可以订阅NetworkChange.NetworkAvailabilityChanged和NetworkChange.NetworkAddressChanged。
通常我会启动一个两秒的计时器,以便在超时后从睡眠模式中恢复网络通信。