Preventing Your Monitor from Going to Sleep with Visual Studio 2012

Introduction

Sometimes it is necessary to prevent your monitor from going asleep while your program is active. At the place I work for, I had to develop a program that counts down the amount of time the student has left on his / her exam. Some of the exams are only theoretical. The problem was that either the screensaver popped up after a few minutes or the monitor went to sleep. This caused the student to not know the exact time remaining. This is what we will do today. We will create a small program illustrating how to prevent the monitor from going to sleep or the screensaver from popping up.

There is no design, obviously you'll have to create a Windows Forms Application with either VB or C#.

Coding

As usual, let us start with the needed Namespaces:

VB.NET

Imports System.Runtime.InteropServices 'APIs
Imports Microsoft.Win32         'For System Events

C#

using System.Runtime.InteropServices; //APIs
using Microsoft.Win32;         //For System Events

Add the following APIs and their constants:

VB.NET

    <FlagsAttribute()> _
    Public Enum EXECUTION_STATE As UInteger ' Determine Monitor State
        ES_AWAYMODE_REQUIRED = &H40
        ES_CONTINUOUS = &H80000000UI
        ES_DISPLAY_REQUIRED = &H2
        ES_SYSTEM_REQUIRED = &H1
        ' Legacy flag, should not be used.
        ' ES_USER_PRESENT = 0x00000004
    End Enum

    '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.
    <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Private Shared Function SetThreadExecutionState(ByVal esFlags As EXECUTION_STATE) As EXECUTION_STATE
    End Function

    'This function queries or sets system-wide parameters, and updates the user profile during the process.
    <DllImport("user32", EntryPoint:="SystemParametersInfo", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Private Shared Function SystemParametersInfo(ByVal uAction As Integer, ByVal uParam As Integer, ByVal lpvParam As String, ByVal fuWinIni As Integer) As Integer
    End Function
    
        Private Const SPI_SETSCREENSAVETIMEOUT As Int32 = 15

C#

        [FlagsAttribute()]
        public enum EXECUTION_STATE : uint //Determine Monitor State
        {
            ES_AWAYMODE_REQUIRED = 0x40,
            ES_CONTINUOUS = 0x80000000u,
            ES_DISPLAY_REQUIRED = 0x2,
            ES_SYSTEM_REQUIRED = 0x1
            // Legacy flag, should not be used.
            // ES_USER_PRESENT = 0x00000004
        }

        //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.
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);

        //This function queries or sets system-wide parameters, and updates the user profile during the process.
        [DllImport("user32", EntryPoint = "SystemParametersInfo", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);

        private const Int32 SPI_SETSCREENSAVETIMEOUT = 15;

Add the KeepMonitorActive sub:

VB.NET

    Public Sub KeepMonitorActive()

        SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED + EXECUTION_STATE.ES_CONTINUOUS) 'Do not Go To Sleep

    End Sub

C#

        public void KeepMonitorActive()
        {

            SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS); //Do not Go To Sleep

        }

The above sub makes use of the SetThreadExecutionState API. This API, according to MSDN, enables an application to inform the system that it is in use, thereby preventing the system from entering sleep mode or turning off the display while the application is running.

We passed the ES_DISPLAY_REQUIRED field indicating that the display needs to be active, until otherwise stated.

The following sub reverses this effect, by removing the ES_DISPLAY_REQUIRED field. Let us add it now:

VB.NET

    Public Sub RestoreMonitorSettings()

        SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS) 'Restore Previous Settings, ie, Go To Sleep Again

    End Sub

C#

        public void RestoreMonitorSettings()
        {
            
            SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS); //Restore Previous Settings, ie, Go To Sleep Again

        }

All that is left for us to be able to use the SetThreadExecutionState API is to call these functions:

VB.NET

    Private Sub btnOpt1Off_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpt1Off.Click

        KeepMonitorActive() 'Option 1 On

    End Sub

    Private Sub btnOpt1On_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpt1On.Click

        RestoreMonitorSettings() 'Option 1 Off

    End Sub

C#

        private void btnOpt1On_Click(System.Object sender, System.EventArgs e)
        {
            
            KeepMonitorActive(); //Option 1 On

        }

        private void btnOpt1Off_Click(System.Object sender, System.EventArgs e)
        {
            
            RestoreMonitorSettings(); //Option 1 Off

        }

One method is done and dusted now. Let us proceed to using the SystemParametersInfo API. The SystemParametersInfo API queries or sets system-wide parameters, and updates the user profile during the process.

Add the next two events:

VB.NET

    Private Sub tmrMonitor_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrMonitor.Tick

        'Option 2
        SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, 5, 0, 0) 'Postpone Sleep For 5 Minutes

    End Sub

    Private Sub btnOpt2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpt2.Click

        tmrMonitor.Enabled = True 'Start Timer

    End Sub

C#

        private void tmrMonitor_Tick(System.Object sender, System.EventArgs e)
        {
            
            //Option 2
            SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, 5, "0", 0); //Postpone Sleep For 5 Minutes
            
        }

        private void btnOpt2_Click(object sender, EventArgs e)
        {
            
            tmrMonitor.Enabled = true; //Start Timer

        }

We enable the timer and this, via the help of the SystemParametersInfo API, postpones the screen from entering sleep mode for 5 minutes at each recursion.

I am attaching both working samples below, just in case you have missed a step.

Conclusion

In this article I illustrated two methods of sleep mode prevention. Obviously which one you'll end up using will depend on your preferences as well as your system. Good luck and see you next time!



Related Articles

Downloads

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Wednesday, September 24, 2014 8:00 AM - 9:00 AM PDT According to a recent Forrester Research report, many companies are choosing low-code platforms over traditional programming platforms, due to the speed with which low-code apps can be assembled and tested. With customer-facing applications on the rise, traditional programming platforms simply can't keep up with the "short schedules and rapid change cycles" required to develop these applications. Check out this upcoming webinar and join Clay Richardson from …

  • The explosion in mobile devices and applications has generated a great deal of interest in APIs. Today's businesses are under increased pressure to make it easy to build apps, supply tools to help developers work more quickly, and deploy operational analytics so they can track users, developers, application performance, and more. Apigee Edge provides comprehensive API delivery tools and both operational and business-level analytics in an integrated platform. It is available as on-premise software or through …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds