我如何知道 Windows 何时进入/退出睡眠或休眠模式?

发布于 2024-07-07 01:04:07 字数 116 浏览 15 评论 0原文

是否可以订阅在 Windows 进入或退出睡眠或休眠状态时触发的 Windows 事件?

我需要让我的应用程序知道计算机何时将进入睡眠状态,以进行一些清理,并避免在计算机退出睡眠状态时出现计时问题。

Is it possible to subscribe to a Windows event that fires when Windows is going into or coming out of Sleep or Hibernate state?

I need my application to be made aware when the computer is going to sleep to do some cleanup and avoid timing issues when it comes out of sleep.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

望她远 2024-07-14 01:04:07

您可以监视 Win32_PowerManagementEvent WMI 事件

You can monitor Win32_PowerManagementEvent WMI event

情话墙 2024-07-14 01:04:07

不确定您想要监视此情况的频率,但如果您在 .NET 中编写服务,您可以覆盖 ServiceBase,将 CanHandlePowerEvent 设置为 true,然后您将通过 PowerBroadcastStatus 枚举收到电源更改通知。

Not sure how often you want to monitor this, but if you write a service in .NET you can override ServiceBase, set CanHandlePowerEvent to true, and then you'll be notified of power changes via the PowerBroadcastStatus enumeration.

时光磨忆 2024-07-14 01:04:07

在 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 上运行的应用程序中使用上述内容进行测试,然后我手动使运行该应用程序的电脑进入睡眠状态,我将看到以下消息:

PBT_APMSUSPEND  received

然后,当电脑重新启动并且我登录时将在调试器输出窗口中看到一条接一条的两条消息:

PBT_APMRESUMESUSPEND  received
PBT_APMRESUMEAUTOMATIC  received

到目前为止我发现的所有内容都表明您没有任何迹象表明您是从睡眠状态还是休眠状态中出来。 我仍在进一步研究文件和设备句柄在暂停或恢复时需要做什么。 我看到有迹象表明 COM 端口的文件句柄在恢复后不再有效。 我也不确定与其他进程的接口,例如数据库连接。

除了标准的睡眠和休眠电源管理状态之外,Microsoft 还引入了 Windows 8 和 8.1 的连接待机电源状态 根据应用程序的类型,它会产生一些应用程序设计影响。

桌面应用程序通常不需要额外的工作来集成
连接待机。

桌面活动管理器 (DAM) 是 Windows 组件
暂停所有桌面应用程序并限制其运行时间
连接待机期间的第三方系统服务。 的目的
DAM 旨在保持与现有软件的基本兼容性
应用程序和服务,但减轻它们对电池寿命的影响
睡觉时。

Windows 会阻止桌面应用程序在任何时间段运行
DAM 阶段完成后连接待机。 Windows 允许
之后以节流模式执行的第三方系统服务
完成DAM阶段。 该模式下可以运行第三方服务
每 30 秒不超过一秒的挂钟时间。

优雅的艺术Intel 的 Lynn Merrill 的《应用程序暂停》提供了一些有关处理与 Windows 下的电源管理相关的各种 Windows 消息类型的信息,但是日期是 2005 年,因此并非所有材料都与 Windows XP 之后的 Windows 相关。 本文档中描述的消息序列中至少有一条不再使用的消息,从 Windows Vista 开始,Windows 不再使用用于请求应用程序是否能够挂起的 PBT_APMQUERYSUSPEND 消息。 SetThreadExecutionState() 函数现在用于指示线程不能因更改为睡眠或休眠状态而中断。 请参阅 stackoverflow 无法捕获睡眠挂起消息 (winxp) 中的答案有关电源管理状态消息更改的详细信息。

自 Windows XP 以来的系统电源状态事件

自 Windows XP 以来,Microsoft 改进了电源管理,因为各个版本的 Windows 操作系统共享更多组件,并且 Windows 版本现在部署在电池较小的设备上,需要更小心的电源管理。 请参阅注册电源事件。 同时存在 RegisterPowerSettingNotification() 函数和 UnregisterPowerSettingNotification() 函数。

应用程序或服务使用RegisterPowerSettingNotification
功能来注册通知。 当相应的功率
设置变更时,系统发送通知如下:

  • 应用程序收到 WM_POWERBROADCAST 消息,其 wParamPBT_POWERSETTINGCHANGE 以及指向
    POWERBROADCAST_SETTING 结构。
  • 服务接收对其通过调用 RegisterServiceCtrlHandlerEx 函数注册的 HandlerEx 回调函数的调用。 这
    发送到 HandlerEx 回调函数的 lpEventData 参数
    指向 POWERBROADCAST_SETTING 结构。

POWERBROADCAST_SETTING结构中,PowerSetting成员
包含标识通知和数据成员的 GUID
包含电源设置的新值。

另请参阅电源管理功能了解列表自 Windows Vista 以来 Windows API 中的电源管理功能。

系统电源状态和电池状况

您可以使用 Windows 系统服务 API 函数 GetSystemPowerStatus() 检索当前电源状态。

检索系统的电源状态。 状态指示是否
系统使用交流电源还是直流电源运行,无论电池是否供电
当前正在充电,电池剩余寿命还有多长,以及是否有电池
保护程序打开或关闭。

但请注意,SYSTEM_POWER_STATUS 结构中返回的信息是有关电池状态和 AC/DC 电源的信息,而不是实际的设备电源状态(例如睡眠或休眠)

如果 Windows 设备处于睡眠或休眠状态,您的应用程序将不会运行,因此该函数无法用于确定当前 Windows 电源状态。 我添加此注释是因为它对于在研究此主题时看到此帖子的人可能有用。

In a Visual Studio 2005 C++ MFC application you will need to add an ON_MESSAGE() to your message map looking for the WM_POWERBROADCAST message as in this example:

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()

Then you will need to add the message handler function along with the class definition change to declare the member function for the message handler so that you can check the wParam variable for the message type as in this skeleton:

// 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;
}

What I have seen is that a test using the above in an application running on Windows 7 that is started in the debugger and then I manually make my PC running the application to Sleep I will see the following message:

PBT_APMSUSPEND  received

Then when the PC is restarted and I sign-in what I will see in the debugger output window are two messages one after the other:

PBT_APMRESUMESUSPEND  received
PBT_APMRESUMEAUTOMATIC  received

Everything that I have found thus far indicates that you have no indication whether you are coming out of a Sleep state or a Hibernate state. I am still doing further research on what needs to be done when suspending or when resuming so far as file and device handles. I have seen indications that file handles to COM ports are no longer valid after resuming. I also am unsure about interfaces to other processes for instance database connections.

In addition to the standard Sleep and Hibernate power management states Microsoft has introduced the Connected Standby power state with Windows 8 and 8.1 which has some application design ramifications depending on the type of application.

Desktop applications typically require no extra work to integrate with
connected standby.

The Desktop Activity Moderator (DAM) is the Windows component that
pauses all desktop applications and throttles the runtime of
third-party system services during connected standby. The purpose of
the DAM is to maintain basic software compatibility with existing
applications and services, but mitigate their impact on battery life
during sleep.

Windows prevents desktop applications from running during any part of
connected standby after the DAM phase completes. Windows allows
third-party system services to execute in a throttled mode after
completing the DAM phase. In this mode, a third-party service can run
for no more than one second of wall-clock time every 30 seconds.

The Art of Graceful Application Suspension by Lynn Merrill from Intel has some information about handling the various Windows message types associated with Power Management under Windows however it is date 2005 so not all material may pertain to Windows after Windows XP. There is at least one no longer used message in the message sequence described in this document as beginning with Windows Vista the PBT_APMQUERYSUSPEND message which was used to request whether an application was able to suspend is no longer used by Windows. The SetThreadExecutionState() function is now used to indicate that a thread can not be interrupted with a change to Sleep or Hibernate state. See the answers in stackoverflow Can't catch sleep suspend messages (winxp) for details on Power Management state message changes.

System power state events since Windows XP

Microsoft has improved power management since Windows XP as the various versions of the Windows OS share more components and versions of Windows are now being deployed on smaller devices with battery requiring more careful power management. See Registering for Power Events. There is both a RegisterPowerSettingNotification() function and an UnregisterPowerSettingNotification() function.

An application or service uses the RegisterPowerSettingNotification
function to register for notifications. When the corresponding power
setting changes, the system sends notifications as follows:

  • An application receives a WM_POWERBROADCAST message with a wParam of PBT_POWERSETTINGCHANGE and an lParam that points to a
    POWERBROADCAST_SETTING structure.
  • A service receives a call to the HandlerEx callback function it registered by calling the RegisterServiceCtrlHandlerEx function. The
    lpEventData parameter sent to the HandlerEx callback function
    points to a POWERBROADCAST_SETTING structure.

In the POWERBROADCAST_SETTING structure, the PowerSetting member
contains the GUID that identifies the notification and the Data member
contains the new value of the power setting.

See also Power Management Functions for the list of the power management functions in the Windows API since Windows Vista.

System power status and battery condition

You can use the Windows System Services API function GetSystemPowerStatus() to retrieve the current power status.

Retrieves the power status of the system. The status indicates whether
the system is running on AC or DC power, whether the battery is
currently charging, how much battery life remains, and if battery
saver is on or off.

However note that the information returned in the SYSTEM_POWER_STATUS struct is about battery status and AC/DC power source and not the actual device power state such as Sleep or Hibernate.

And if the Windows device is in a Sleep or Hibernate state, your application will not be running so this function can not be used to determine the current Windows power state. I include this note as it may be useful for someone who arrives at this post while researching this topic.

做个少女永远怀春 2024-07-14 01:04:07

Microsoft.Win32.SystemEvents.PowerModeChanged 活动将为您提供此信息。 该事件在 Microsoft 迄今为止发布的 .NET 框架的所有变体中都可用。

Microsoft.Win32.SystemEvents.PowerModeChanged event will give you this information. This event is available in all variants of the .NET framework released by Microsoft so far.

铃予 2024-07-14 01:04:07

在 .NET 中,使用 PowerModeChanged 事件。
在 Win32 中,使用 WM_POWERBROADCAST 消息。

In .NET, use the PowerModeChanged event.
In Win32, use the WM_POWERBROADCAST message.

梦里°也失望 2024-07-14 01:04:07

您可以订阅 NetworkChange.NetworkAvailabilityChanged 和 NetworkChange.NetworkAddressChanged。

我通常会启动一个两秒定时器,以便在超时后可以在处于睡眠模式后恢复网络通信。

You can subscribe to NetworkChange.NetworkAvailabilityChanged and NetworkChange.NetworkAddressChanged.

I generally start a two second timer so that I can resume network communications after being in sleep mode when it times out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文