Why Disable the Screensaver?
Screensaver software was originally created in order that still images were not shown on a computer display when the system was inactive. Instead, the screensaver would show moving images or a dark screen. Brightly coloured, static images can cause permanent screen damage, known as screen burn, in displays based upon cathode ray tube (CRT) or plasma technology. They can also cause temporary image persistence in liquid crystal displays (LCD). Although image persistence is temporary, it can be distracting so the use of a screensaver is often recommended for such displays.
If a screensaver has been enabled by the user, Microsoft Windows will show it after a period of inactivity. Windows has two built-in timers, known as the display idle timer and the system idle timer. These are used to determine the amount of time that has passed since the user provided some input, such as pressing a key, moving the mouse or touching a touch-sensitive screen. They are reset to zero in response to any of these actions. When the display idle timer reaches a pre-configured value, the screensaver starts. If the system idle timer expires, the system may be suspended. The lengths of time involved and whether the computer is put to sleep or not are configured in the screensaver and power options of the Control Panel.
Some software applications require that the screensaver is not displayed or that the machine is prevented from sleeping. For example, if you develop a video player or some presentation software, your users would not want the presentation to be interrupted by the screensaver. If your software provides a continuous service, such as acting as a fax server, you may want the screensaver enabled but you will want to prevent the computer from suspending automatically.
The .NET framework classes don't provide a way to disable the screensaver or sleep mode, so we need to use Platform Invocation Services (P/Invoke) to call a Windows API function named, "SetThreadExecutionState". This function tells the operating system that the thread is in use, even if the user is not interacting with the computer. This can prevent the display from being hidden and stop the machine from being suspended automatically.
SetThreadExecutionState uses a series of flags to specify a new state for the current thread. We'll define these flags shortly using an enumeration with the Flags attribute. You can use the logical OR operator to combine several flags and specify multiple behaviours with a single call. The function returns a value made up from the same flags. The return value indicates the state before the changes that you requested, or returns null if there is an error.
The four flags that we are interested in are:
- ES_DISPLAY_REQUIRED. This flag indicates that the display is in use. When passed by itself, the display idle timer is reset to zero once. The timer restarts and the screensaver will be displayed when it next expires.
- ES_SYSTEM_REQUIRED. This flag indicates that the system is active. When passed alone, the system idle timer is reset to zero once. The timer restarts and the machine will sleep when it expires.
- ES_CONTINUOUS. This flag is used to specify that the behaviour of the two previous flags is continuous. Rather than resetting the idle timers once, they are disabled until you specify otherwise. Using this flag means that you do not need to call SetThreadExecutionState repeatedly.
- ES_AWAYMODE_REQUIRED. This flag must be combined with ES_CONTINUOUS. If the machine is configured to allow it, this indicates that the thread requires away mode. When in away mode the computer will appear to sleep as normal. However, the thread will continue to execute even though the computer has partially suspended. As this flag gives the false impression that the computer is in a low power state, you should only use it when absolutely necessary.
Declaring the API Function
The code we need to declare the API function and the EXECUTION_STATE enumeration is shown below:
static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
enum EXECUTION_STATE : uint
ES_AWAYMODE_REQUIRED = 0x00000040,
ES_CONTINUOUS = 0x80000000,
ES_DISPLAY_REQUIRED = 0x00000002,
ES_SYSTEM_REQUIRED = 0x00000001
NB: Disabling sleep mode using SetThreadExecutionState only prevents the computer from suspending due to the expiry of the system idle timer. You cannot prevent the computer from being suspended manually by a user.
Disabling the Screensaver
With the API declared, it is a simple matter to create a method that disables the screensaver. To disable it until we state otherwise, we use the ES_DISPLAY_REQUIRED and ES_CONTINUOUS flags. Here the method is declared as static so that it can be easily called from the Main method of a test program.
public static void Disable()
EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
Re-enabling the Screensaver
Re-enabling the screensaver requires that we clear the ES_DISPLAY_REQUIRED state flag. We can do this by passing the ES_CONTINUOUS flag alone:
public static void Enable()
17 May 2012