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.
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.
In .NET, use the PowerModeChanged event.
In Win32, use the WM_POWERBROADCAST message.
You can monitor Win32_PowerManagementEvent WMI event
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.
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.
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.