是否可以订阅Windows进入或退出睡眠或休眠状态时触发的Windows事件?
我需要让我的应用程序在计算机进入睡眠状态时进行清理并避免在睡眠时出现计时问题。
Microsoft.Win32.SystemEvents.PowerModeChanged
活动将为您提供此信息。到目前为止,Microsoft发布的.NET框架的所有变体都提供此事件。
在.NET中,使用PowerModeChanged事件。在Win32中,使用WM_POWERBROADCAST消息。
您可以监控Win32_PowerManagementEvent WMI事件
不确定您希望监视此频率的频率,但如果您在.NET中编写服务,则可以覆盖ServiceBase,将CanHandlePowerEvent设置为true,然后通过PowerBroadcastStatus枚举通知您电源更改。
在Visual Studio 2005 C ++ MFC应用程序中,您需要将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;
}
我所看到的是,在调试器中启动的Windows 7上运行的应用程序中使用上述测试,然后我手动使我的PC运行应用程序到睡眠我将看到以下消息:
PBT_APMSUSPEND received
然后当PC重新启动并且我在调试器输出窗口中登录时会看到两个消息:
PBT_APMRESUMESUSPEND received
PBT_APMRESUMEAUTOMATIC received
到目前为止我发现的所有内容都表明您没有迹象表明您是否已退出睡眠状态或休眠状态。我还在进行进一步的研究,研究在暂停或恢复文件和设备句柄时需要做什么。我看到有迹象表明COM端口的文件句柄在恢复后不再有效。我也不确定与其他进程的接口,例如数据库连接。
除了标准的Sleep和Hibernate电源管理状态之外,Microsoft还引入了Connected Standby power state with Windows 8 and 8.1,它具有一些应用程序设计的后果,具体取决于应用程序的类型。
桌面应用程序通常不需要额外的工作就可以与连接的备用数
桌面活动主持人(DAM)是Windows组件,它会暂停所有桌面应用程序并在连接待机期间限制第三方系统服务的运行时。 DAM的目的是保持与现有应用程序和服务的基本软件兼容性,但减轻它们在睡眠期间对电池寿命的影响。
在DAM阶段完成后,Windows会阻止桌面应用程序在连接待机的任何部分运行。 Windows允许第三方系统服务在完成DAM阶段后以限制模式执行。在此模式下,第三方服务每隔30秒可以运行不超过一秒的挂钟时间。
来自英特尔的The Art of Graceful Application Suspension by Lynn Merrill有一些关于在Windows下处理与Power Management相关的各种Windows消息类型的信息,但它是2005年的日期,因此并非所有材料都可能与Windows XP之后的Windows相关。在本文档中描述的消息序列中至少有一条不再使用的消息,从Windows Vista开始,用于请求应用程序是否能够挂起的PBT_APMQUERYSUSPEND
消息不再被Windows使用。 SetThreadExecutionState()
函数现在用于指示线程不能通过更改Sleep或Hibernate状态来中断。有关电源管理状态消息更改的详细信息,请参阅stackoverflow Can't catch sleep suspend messages (winxp)中的答案。
您可以订阅NetworkChange.NetworkAvailabilityChanged和NetworkChange.NetworkAddressChanged。
我通常会启动一个两秒钟的计时器,以便在超时后处于睡眠模式时恢复网络通信。