Search code examples
c#windows-screensaver

How to interrupt Screen-saver under windows 8


I would like know how to interrupt Screen-saver under the Windows 8(Embedded version) or Windows 10, Because a window(C#) of my project only run under the normal status, otherwise it will be error if run under Screen-saver. so I want to interrupt the Screen-saver before this window pop-up.

I have researched some solution and idea that included as below,

  • a. Move mouse(used the user32's mouse_event api)
  • b. Send keys(also used the user32's api)
  • c. Kill screen-saver process.

Both of a & b are ways I have tried them and worked well on the windows 10, but not worked on the Windows 8(Embedded version), so currently I only focus on the c way, about way of c I searched the as below link,

https://support.microsoft.com/en-us/help/140723/how-to-force-a-screen-saver-to-close-once-started-in-windows-nt,-windows-2000,-and-windows-server-2003

https://www.codeproject.com/Articles/17067/Controlling-The-Screen-Saver-With-C

but above links still aren't work on the windows 10 and Windows 8(Embedded version), which expert give me some suggestion? thanks in advance.


Solution

  • Have a look at the unmanaged API functions GetSystemPowerStatus and SetThreadExecutionState. Using a (thread) timer, you can periodically update the status, e.g. from a class property, and inform the system about your requirements. This is useful, if your application may allow or disallow the screensaver, depending on it's operating state.

    public class PowerManager : IDisposable
    {
      [Flags]
      public enum ExecutionStateEnum : uint
      {
        LetTheSystemDecide    = 0x00,
        SystemRequired        = 0x01,
        SystemDisplayRequired = 0x02,
        UserPresent           = 0x04,
        Continuous            = 0x80000000,
      }
    
      [DllImport("kernel32")]
      private static extern uint SetThreadExecutionState(ExecutionStateEnum esFlags);
    
      public PowerManager() {}
    
      public Update(ExecutionStateEnum state)
      {
        SetThreadExecutionState(state);
      }
    }
    

    Update:

    Then call PowerManager.Update(ExecutionStateEnum.SystemDisplayRequired) to disable the screensaver or call PowerManager.Update(ExecutionStateEnum.LetTheSystemDecide) to restore the default system behaviour (allow the screensaver). If the method is called periodically from a timer callback, adjust the timer interval according to the configured screensaver timeout.