Stay-awake utility for Windows Vista and 7 (C#)

If a scheduled task (for example a nightly custom backup job) is configured to wake the system from hybrid sleep state, you may experience that the system powers down again after two minutes, even though the scheduled job is not done yet. This happens because Vista and 7 expects scheduled programs to actively tell it if the system and/or the display are required while the task is running.

Another problem scenario is the computer going to sleep in the middle of executing a user initiated long-running process at a time of day where the computer is unattended.

The following utility can be used to tell the power management system not to put the computer into hybrid sleep for a specified number of minutes. The utility takes the desired number of minutes as a command line argument, like this:

StayAwake.exe 60

If executed synchronously, the program will automatically re-launch itself asynchronously in a separate process to avoid blocking execution of the program/script from which it was called. It is available for download as an executable file including C# source code. There are two pre-compiled packages; One for Microsoft.Net Framework version 2.0 and one for version 4.0:

Download Stay Awake 0.22 for .net 2.0

Download Stay Awake 0.22 for .net 4.0

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
public class StayAwake
{
  public static void Main(String[] args)
  {
    if (args.Length < 1)
    {
      Console.WriteLine("Stay awake 0.22 - Keeps the OS from sleeping");
      Console.WriteLine();
      Console.WriteLine("Missing argument. Syntax: StayAwake minutes");
      Console.WriteLine();
      Console.WriteLine("Example: StayAwake 60");
      Console.WriteLine();
    }
    else if (args.Length == 1)
    {
      if (IsInteger(args[0]))
      {
        Process proc = new Process();
        proc.StartInfo.FileName = Assembly.GetExecutingAssembly().Location;
        proc.StartInfo.Arguments = args[0] + " RunSync";
        proc.Start();
      }
      else
      {
        Console.WriteLine("Not an integer");
      }
    }
    else if (args.Length == 2)
    {
      if (IsInteger(args[0]))
      {
        SleeplessWait(Convert.ToInt32(args[0]));
      }
      else
      {
        Console.WriteLine("Not an integer");
      }
    }
  }

  [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  static extern EXECUTION_STATE SetThreadExecutionState(
  EXECUTION_STATE flags);
  [Flags]
  
  public enum EXECUTION_STATE : uint
  {
    ES_SYSTEM_REQUIRED = 0x00000001,
    ES_DISPLAY_REQUIRED = 0x00000002,
    ES_CONTINUOUS = 0x80000000
  }

  public static void SleeplessWait(int minutes)
  {
    SetThreadExecutionState(
      EXECUTION_STATE.ES_SYSTEM_REQUIRED |
      EXECUTION_STATE.ES_CONTINUOUS);
    try
    {
      DateTime startTime = DateTime.Now;
      DateTime endTime;
      endTime = DateTime.Now + new TimeSpan(0, minutes, 0);
      Console.WriteLine("Staying awake until " + endTime);
      Thread.Sleep(minutes * 60000);
    }
    catch (Exception e)
    {
      Console.WriteLine(e.Message);
    }
    finally
    {
      SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);
    }    
  }
  
  public static bool IsInteger(string aString)
  {
    try
    {
      Convert.ToInt32(aString);
      return true;
    }
    catch
    {
      return false;
    }
  }
}

The above version of the code only prevents the system from going into sleep mode. If the display needs to be active during the wake period, insert "EXECUTION_STATE.ES_DISPLAY_REQUIRED |" at line 62.

Tags: software
Page last updated 2010-01-16 17:46. Some rights reserved (CC by 3.0)