How to prevent Windows from entering idle state?

后端 未结 5 1012
执念已碎
执念已碎 2020-11-27 14:38

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 Win

相关标签:
5条回答
  • 2020-11-27 14:59

    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;
    }
    
    0 讨论(0)
  • 2020-11-27 15:03

    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.

    0 讨论(0)
  • 2020-11-27 15:07

    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);
    
    0 讨论(0)
  • 2020-11-27 15:13

    Here is SetThreadExecutionState C# implementation

    0 讨论(0)
  • 2020-11-27 15:21

    You can use SetThreadExecutionState described here:

    • SetThreadExecutionState Function

    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:

    • PInvoke.net: setthreadexecutionstate (kernel32)
    0 讨论(0)
提交回复
热议问题