Alex Rivera | Logout

C# .NET: How to check if we're running on battery?

Asked 2008-10-27T19:33:11.597
29

i want to be a good developer citizen, pay my taxes, and disable things if we're running over Remote Desktop, or running on battery.

If we're running over remote desktop (or equivalently in a Terminal server session), we must disable animations and double-buffering. You can check this with:

/// <summary>
/// Indicates if we're running in a remote desktop session.
/// If we are, then you MUST disable animations and double buffering i.e. Pay your taxes!
/// 
/// </summary>
/// <returns></returns>
public static Boolean IsRemoteSession
{
    //This is just a friendly wrapper around the built-in way
    get
    {
        return System.Windows.Forms.SystemInformation.TerminalServerSession;
    }
}

Now i need to find out if the user is running on battery power. If they are, i don't want to blow through their battery. i want to do things such as

  • disable animations
  • disable background spell-checking
  • disable background printing
  • turn off gradients
  • use graphics.SmoothingMode = SmoothingMode.HighSpeed;
  • use graphics.InterpolationMode = InterpolationMode.Low;
  • use graphics.CompositingQuality = CompositingQuality.HighSpeed;
  • minimize hard drive access - to avoid spin up
  • minimize network access - to save WiFi power

Is there a managed way to see if the machine is currently running on battery?

Bonus Reading

Edit
Report

1 Answer

8

You could use the GetSystemPowerStatus function using P/Invoke. See: http://msdn.microsoft.com/en-gb/library/aa372693.aspx

Here's an example:

using System;
using System.Runtime.InteropServices;
namespace PowerStateExample
{
    [StructLayout(LayoutKind.Sequential)]
    public class PowerState
    {
        public ACLineStatus ACLineStatus;
        public BatteryFlag BatteryFlag;
        public Byte BatteryLifePercent;
        public Byte Reserved1;
        public Int32 BatteryLifeTime;
        public Int32 BatteryFullLifeTime;

        // direct instantation not intended, use GetPowerState.
        private PowerState() {}

        public static PowerState GetPowerState()
        {
            PowerState state = new PowerState();
            if (GetSystemPowerStatusRef(state))
                return state;

            throw new ApplicationException("Unable to get power state");
        }

        [DllImport("Kernel32", EntryPoint = "GetSystemPowerStatus")]
        private static extern bool GetSystemPowerStatusRef(PowerState sps);
    }

    // Note: Underlying type of byte to match Win32 header
    public enum ACLineStatus : byte
    {
        Offline = 0, Online = 1, Unknown = 255
    }

    public enum BatteryFlag : byte
    {
        High = 1, Low = 2, Critical = 4, Charging = 8,
        NoSystemBattery = 128, Unknown = 255
    }

    // Program class with main entry point to display an example.
    class Program
    {        
        static void Main(string[] args)
        {
            PowerState state = PowerState.GetPowerState();
            Console.WriteLine("AC Line: {0}", state.ACLineStatus);
            Console.WriteLine("Battery: {0}", state.BatteryFlag);
            Console.WriteLine("Battery life %: {0}", state.BatteryLifePercent);
        }
    }
}
answered 2008-10-27T19:37:55.783

Your Answer