Welcome to MSDN Blogs Sign in | Join | Help

Give your computer insomnia [Free tool and source code to temporarily prevent a machine from going to sleep!]

The default power settings for Windows are set up so a computer will go to sleep after 15 to 30 minutes of inactivity (i.e., no mouse or keyboard input). This is great because a computer that's not being used doesn't need to be running at full power. By letting an idle machine enter sleep mode, the user benefits from a significant reduction in electricity use, heat generation, component wear, etc.. And because sleep mode preserves the state of everything in memory, it's quick to enter, quick to exit, and doesn't affect the user's work-flow. All the same applications continue running, windows stay open and where they were, etc.. So sleep mode is a Good Thing and I'm a fan.

However, sometimes a computer is busy even though someone isn't actively using the mouse and keyboard; common examples include playing a movie, burning a DVD, streaming music, etc.. In these cases, you don't want the machine to go to sleep because you're using it - even though you're not actually using it! So most media players and disc burners tell Windows not to go to sleep while they're running. In fact, there's a dedicated API for exactly this purpose: the SetThreadExecutionState Win32 Function.

But what about those times when the computer is busy doing something and the relevant program doesn't suppress the default sleep behavior? For example, it might be downloading a large file, re-encoding a music collection, backing up the hard drive, or hashing the entire contents of the disk. You don't want the machine to go to sleep for now, but are otherwise happy with the default sleep behavior. Unfortunately, the easiest way I know of to temporarily suppress sleeping is to go to Control Panel, open the Power Options page, change the power plan settings, commit them - and then remember to undo everything once the task is finished. It's not hard; but it's kind of annoying...

 

So here's a better way:

Insomnia application

Insomnia is a simple WPF application that calls the SetThreadExecutionState API to disable sleep mode for as long as it's running. (Note that the display can still power off during this time - it's just sleep for the computer that's blocked.) Closing the Insomnia window immediately restores whatever sleep mode was in effect before it was run. It couldn't be easier!

 

[Click here to download the Insomnia application along with its complete source code.]

 

Notes:

  • Insomnia basically boils down to a single function call - but to a function that's a Win32 API and is not part of the .NET Framework. This is where a very powerful feature saves the day: Platform Invoke. For those who aren't familiar with it, P/Invoke (as it's called) lets a managed application call into the APIs exposed by a native DLL. All it takes is a dash of the DllImport attribute and a little bit of translation from the Win32 types to their managed counterparts. The MSDN documentation goes into lots of detail here, and I encourage interested parties to go there.
  • One popular resource for P/Invoke assistance is PInvoke.net, where you can find managed definitions for hundreds of native APIs. But I usually just end up creating my own - if nothing else, it's a good learning exercise. :)
  • The Insomnia window has its Topmost property set to True so it's always visible and people will be less likely to accidentally leave their computers sleep-less. Other than taking up a small bit of screen space and memory, Insomnia consumes no system resources, so it won't get in the way of whatever else is running.
  • It is considered polite to leave things the way you found them, so Insomnia makes an extra call to SetThreadExecutionState when it's closed in order to restore things to how they were. However, this is really more for show than anything else, because the execution state is clearly per-thread and Insomnia's thread is about to die anyway.
  • I did a quick web search for similar tools before I wrote Insomnia and there are a few out there. Most of what I found was for Linux and Mac for some reason, but I'm sure Insomnia isn't the first of its kind for Windows. However, that doesn't stop it from being a nice introduction to P/Invoke - and besides, I'm always happier running my own code! :)

 

Finally, here's the implementation:

public partial class Window1 : Window
{
    private uint m_previousExecutionState;

    public Window1()
    {
        InitializeComponent();

        // Set new state to prevent system sleep (note: still allows screen saver)
        m_previousExecutionState = NativeMethods.SetThreadExecutionState(
            NativeMethods.ES_CONTINUOUS | NativeMethods.ES_SYSTEM_REQUIRED);
        if (0 == m_previousExecutionState)
        {
            MessageBox.Show("Call to SetThreadExecutionState failed unexpectedly.",
                Title, MessageBoxButton.OK, MessageBoxImage.Error);
            // No way to recover; fail gracefully
            Close();
        }
    }

    protected override void OnClosed(System.EventArgs e)
    {
        base.OnClosed(e);

        // Restore previous state
        if (0 == NativeMethods.SetThreadExecutionState(m_previousExecutionState))
        {
            // No way to recover; already exiting
        }
    }

    private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
    {
        // Start an instance of the NavigateUri (in a browser window)
        Process.Start(((Hyperlink)sender).NavigateUri.ToString());
    }
}

internal static class NativeMethods
{
    // Import SetThreadExecutionState Win32 API and necessary flags
    [DllImport("kernel32.dll")]
    public static extern uint SetThreadExecutionState(uint esFlags);
    public const uint ES_CONTINUOUS = 0x80000000;
    public const uint ES_SYSTEM_REQUIRED = 0x00000001;
}
Published Wednesday, September 30, 2009 8:41 PM by Delay
Filed under: ,

Comments

# re: Give your computer insomnia [Free tool and source code to temporarily prevent a machine from going to sleep!]

Friday, October 02, 2009 2:31 AM by mrjvdveen

Nice tool. I do have to say that Windows 7 does a much better job on putting a computer to sleep only when possible. If I for example have my p2p client active it will not go to sleep, but as soon as I shut it down, it does. Also when I use mediacenter and schedule a recording it will go to sleep but will wake up in time to start recording. Really cool stuff.

I'm not sure if they changed stuff in the API though.

# re: Give your computer insomnia [Free tool and source code to temporarily prevent a machine from going to sleep!]

Saturday, October 03, 2009 9:10 AM by anonymuos

Now all you need to do is:

1.  Add an option to start it only in the tray.

2.  Hide the tray icon by default when run once as an option and make it appear if run the second time.

3.  Add a minimize button.

4.  Pretty it up a little bit.

# re: Give your computer insomnia [Free tool and source code to temporarily prevent a machine from going to sleep!]

Sunday, October 04, 2009 2:37 AM by Delay

anonymuos,

I touch on this in the post a bit, but I had a specific goal with Insomnia that it should NOT be possible/easy for the user to forget that the program was running and suppressing the default sleep action (and also that the application should be super-easy to use). This goal seems to be in fairly direct opposition to your suggestions 1, 2, and 3, and that's part of the reason I didn't take that approach already. Regarding your suggestion 4, I have no defense, save to admit that I have no measurable design skills whatsoever and beg your forgiveness for the ugly UIs I tend to come up with. :)

Anonymous comments are disabled
 
Page view tracker