Click here to Skip to main content
15,867,330 members
Articles / Programming Languages / C#

Responding to Windows power management events (standby, hibernate, shutdown)

Rate me:
Please Sign up or sign in to vote.
4.60/5 (8 votes)
6 May 2011CPOL2 min read 61K   1.8K   21   11
Making your application exit gracefully by handling Windows power management events (standby, hibernate, shutdown)

Introduction

This article provides a way for a .NET Windows application to respond to Windows Power Management events such as suspend, hibernate, standby, power switch, etc.

Background

My organization uses Lotus Notes as an email client which hangs badly on our laptops when we go from one meeting room to another since the network breaks between the meeting rooms. And since Lotus Notes continuously monitors the network for any incoming mail, it tends to get hung up taking the whole window down with it. So to avoid forcefully restarting Windows, I created this application to capture the standby event and close the mail client before going to standby and automatically start the mail client when the system resumes. I got a lot of reference help from the following article:

Using the Code

We need to override the WndProc method which will allow us to interact with all the events that the OS tends to provide to the application on different conditions.

The Windows OS communicates with the application by sending different messages which need to be captured and worked on. For this implementation, we need to capture the WM_POWERBROADCAST (0x0218) value which will specify that this is a power event change and that we need to capture the WParam which can have the following values:

  • PBT_APMQUERYSUSPEND (0x0000)
  • PBT_APMRESUMESUSPEND (0x0007)
  • PBT_APMQUERYSTANDBY (0x0001)
  • PBT_APMQUERYSUSPENDFAILED (0x0002)
  • PBT_APMQUERYSTANDBYFAILED (0x0003)
  • PBT_APMSUSPEND (0x0004)
  • PBT_APMSTANDBY (0x0005)
  • PBT_APMRESUMECRITICAL (0x0006)
  • PBT_APMRESUMESTANDBY (0x0008)
  • PBTF_APMRESUMEFROMFAILURE (0x00000001)
  • PBT_APMBATTERYLOW (0x0009)
  • PBT_APMPOWERSTATUSCHANGE (0x000A)
  • PBT_APMOEMEVENT (0x000B)
  • PBT_APMRESUMEAUTOMATIC (0x0012)

These values will help us to manage the application data when a power management event occurs. More details of the messages passed to the application are available at this link.

C#
/// <summary>
/// Overloaded System Windows Handler.
/// </summary>
/// <param name="m">Message <see cref="Message"/> structure</param>
protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case WM_POWERBROADCAST:
            switch (m.WParam.ToInt32())
            {
                //value passed when system is going on standby / suspended
                case PBT_APMQUERYSUSPEND:
                    List<string> arr = 
                      Properties.Settings.Default.StandDownApps.Split(',').ToList();
                    foreach (string item in arr)
                    {
                        foreach (Process p in 
                           System.Diagnostics.Process.GetProcessesByName(item))
                        {
                            try
                            {
                                //Exiting the applications when going into standby
                                p.Kill();
                                p.WaitForExit(3600000); // 1 min timeout
                            }
                            catch
                            {
                                // process was terminating or can't be terminated
                            }
                        }
                    }
                    break;
                //value passed when system is resumed after suspension.
                case PBT_APMRESUMESUSPEND:
                    arr = Properties.Settings.Default.StandUpApps.Split(',').ToList();
                    foreach (string item in arr)
                    {
                        //Starting the applications when coming up from standby
                        System.Diagnostics.Process.Start(item);
                    }
                    break;

                //value passed when system Suspend Failed
                case (PBT_APMQUERYSUSPENDFAILED):
                //value passed when system is suspended
                case (PBT_APMSUSPEND):
                //value passed when system is resumed automatically
                case (PBT_APMRESUMEAUTOMATIC):
                //value passed when system is resumed from critical
                //suspension possibly due to battery failure
                case (PBT_APMRESUMECRITICAL):
                //value passed when system is low on battery
                case (PBT_APMBATTERYLOW):
                //value passed when system power status changed
                //from battery to AC power or vice-a-versa
                case (PBT_APMPOWERSTATUSCHANGE):
                //value passed when OEM Event is fired. Not sure what that is??
                case (PBT_APMOEMEVENT):
                    break;
            }
            break;
        default:
            break;
    }
    base.WndProc(ref m);
}

Points of Interest

The main learning point was how to capture the events for standby, suspend, and resume of Windows which will be useful to gracefully handle these kinds of events to prevent data from getting corrupted.

History

  • Version 1.0 - Initial draft (5th May 2011)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Program Manager Capgemini
United States United States
I have been working in software industry for the past 11 years, though i am trained to be a pharmacist. Enjoy working on complex and new technologies. Also cleared my SCJP and MCP certification examinations.

Comments and Discussions

 
GeneralMy vote of 1 Pin
Cristian Amarie7-May-11 0:18
Cristian Amarie7-May-11 0:18 
No real value here other than constant enumeration.
And the
<pre>p.Kill();
p.WaitForExit(3600000); // 1 min timeout</pre>
is really a horror. Kill and wait one minute? What if you have 20 processes? You will wait 20 minutes to sleep the computer? C'mon.

Nuclear launch detected

GeneralRe: My vote of 1 Pin
Chris Maunder7-May-11 1:02
cofounderChris Maunder7-May-11 1:02 
GeneralRe: My vote of 1 Pin
Cristian Amarie7-May-11 2:16
Cristian Amarie7-May-11 2:16 
GeneralRe: My vote of 1 Pin
Chris Maunder7-May-11 6:53
cofounderChris Maunder7-May-11 6:53 
GeneralRe: My vote of 1 Pin
Sandeep Mewara7-May-11 19:07
mveSandeep Mewara7-May-11 19:07 
GeneralRe: My vote of 1 Pin
Cristian Amarie8-May-11 2:11
Cristian Amarie8-May-11 2:11 
GeneralRe: My vote of 1 Pin
Sandeep Mewara8-May-11 2:20
mveSandeep Mewara8-May-11 2:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.