48

I am working on a C# application which runs in the background without any Windows control.

I want to notify Windows that my application is still alive to prevent Windows from going into the idle state.

Are there any APIs available to call from my application which notify the Windows OS that my application is still alive?

Thanks in advance.

doncherry
  • 259
  • 3
  • 14
user724789
  • 521
  • 1
  • 4
  • 3
  • 6
    Be sure to let your users somehow know that the application needs to be run continuously and that it prevents Windows from going idle. This is especially important for users with laptops. – In silico Jun 10 '11 at 05:31

5 Answers5

44

You've to use SetThreadExecutionState function. Something like this:

public partial class MyWinForm: Window
{
    private uint fPreviousExecutionState;

    public Window1()
    {
        InitializeComponent();

        // Set new state to prevent system sleep
        fPreviousExecutionState = NativeMethods.SetThreadExecutionState(
            NativeMethods.ES_CONTINUOUS | NativeMethods.ES_SYSTEM_REQUIRED);
        if (fPreviousExecutionState == 0)
        {
            Console.WriteLine("SetThreadExecutionState failed. Do something here...");
            Close();
        }
    }

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

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

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;
}
Joao
  • 7,366
  • 4
  • 32
  • 48
  • on some Windows XP machines of our clients, the NativeMethods.SetThreadExecutionState never returns 0, any idea? – Alessio Mar 23 '15 at 11:52
  • 5
    @Alessio - a return of `0` means the method failed. From the documentation of `SetThreadExecutionState` - "If the function succeeds, the return value is the previous thread execution state. If the function fails, the return value is NULL." (Note - I am assuming you probably already had figured that out, but wanted to post an answer for completeness and to help anyone else who might come along and view your comment) – pstrjds Jun 14 '16 at 09:36
  • 1
    In trying to resolve a recurring and hard to resolve sleep issue with a Surface Pro 3 running windows 8.1, I can state with clarity that this solution unfortunately does not work for this issue on this OS. – Redgum Aug 24 '16 at 23:50
  • 3
    Could be me but this doesnt seem t work in Windows 10 – ecklerpa Dec 06 '17 at 19:27
  • 2
    Worked for me in Win 10 @ecklerpa. Also, if anyone needs to do this for a visible appliaction, also remember to set ES_DISPLAY_REQUIRED to avoid the display turning off. – Magnus Akselvoll Mar 08 '18 at 07:23
  • I am using Windows Server 2012 and the same solution is not working for me. I have hosted table dependency inside windows service and same is not working. I have mentioned the details at https://github.com/christiandelbianco/monitor-table-change-with-sqltabledependency/issues/61 . – Ashish Shukla May 30 '18 at 08:40
  • Does this method prevent Sleep Mode when a user selects "WindowsKey|Power|Sleep"? My tests show that it does not. Is there a way that does? – Kevin S. Miller Jan 27 '20 at 16:02
22

You have a couple of options:

  • Use SetThreadExecutionState, which:

    Enables an application to inform the system that it is in use, thereby preventing the system from entering sleep or turning off the display while the application is running.

    Where you could use the ES_SYSTEM_REQUIRED flag to

    Forces the system to be in the working state by resetting the system idle timer.

  • Use SendInput to fake keystroke, mouse motion/clicks

  • Another alternative would be to change your app to be a Windows service.

SetThreadExecutionState example

// Television recording is beginning. Enable away mode and prevent
// the sleep idle time-out.
SetThreadExecutionState(
    ES_CONTINUOUS | 
    ES_SYSTEM_REQUIRED | 
    ES_AWAYMODE_REQUIRED);

// Wait until recording is complete...
// Clear EXECUTION_STATE flags to disable away mode and allow the system
// to idle to sleep normally.
SetThreadExecutionState(ES_CONTINUOUS);
Gustavo Mori
  • 8,319
  • 3
  • 38
  • 52
10

You can use SetThreadExecutionState described here:

Since it is a Win32 API function, to use it from C# you'll need to PInvoke it. The steps are described here, including a sample method PreventSleep to temporarily disable sleep mode:

Rick Sladkey
  • 33,988
  • 6
  • 71
  • 95
0

I don't think there's any way to do this directly in managed code.

A quick search reveals this post from 2 years ago. Basically you'd need to do some interop to call a raw windows API.

Community
  • 1
  • 1
Tremmors
  • 2,906
  • 17
  • 13
-3

Here is SetThreadExecutionState C# implementation

Draken
  • 3,134
  • 13
  • 34
  • 54
JDE
  • 294
  • 1
  • 12