Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Windows power plans/schemes in C# (using WinAPI)

I'm interested in getting all power plans that you have in your computer using C#.

I was thinking you might be able to use the API PowerEnumerate function in some way:

DWORD WINAPI PowerEnumerate(
  _In_opt_   HKEY RootPowerKey,
  _In_opt_   const GUID *SchemeGuid,
  _In_opt_   const GUID *SubGroupOfPowerSettingsGuid,
  _In_       POWER_DATA_ACCESSOR AccessFlags,
  _In_       ULONG Index,
  _Out_opt_  UCHAR *Buffer,
  _Inout_    DWORD *BufferSize
);

But I have no idea on how to as I really don't know C. So.. How can I like, enumerate through all available power plans and create a a list of them. I then want to be able to access each power plans GUID and their "user friendly name".

So.. Perhaps if someone who is good at using the WinAPI from C# who would like to help, that would be great - or if someone has a better solution. I've really tried to find a good answer to this but there doesn't seem to be any. I think this would help a lot of people.

Can anyone help with this?

like image 918
hsson Avatar asked Oct 09 '14 23:10

hsson


People also ask

How do I check my Windows power plan?

Confirm that the default power planClick Start, and then select Control Panel. Click Hardware and Sound, and then select Power Options. The Power Options Control Panel opens, and the power plans appear. Review each power plan.

How do I find hidden power plans in Windows 10?

You can unhide the other Power Plans by running this Command: Type CMD in Start Search, right click Command Prompt result to Run as Administrator. Copy and paste powercfg -restoredefaultschemes and press Enter. I hope this helps.

How do I get additional power plans?

Right-click on the battery icon in the Taskbar and select Power Options. You may need to click on Show Additional Plans to see the full list.


1 Answers

This should do it:

using System;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections.Generic;

public class Program
{
    [DllImport("PowrProf.dll")]
    public static extern UInt32 PowerEnumerate(IntPtr RootPowerKey, IntPtr SchemeGuid, IntPtr SubGroupOfPowerSettingGuid, UInt32 AcessFlags, UInt32 Index, ref Guid Buffer, ref UInt32 BufferSize);

    [DllImport("PowrProf.dll")]
    public static extern UInt32 PowerReadFriendlyName(IntPtr RootPowerKey, ref Guid SchemeGuid, IntPtr SubGroupOfPowerSettingGuid, IntPtr PowerSettingGuid, IntPtr Buffer, ref UInt32 BufferSize);

    public enum AccessFlags : uint
    {
        ACCESS_SCHEME = 16,
        ACCESS_SUBGROUP = 17,
        ACCESS_INDIVIDUAL_SETTING = 18
    }

    private static string ReadFriendlyName(Guid schemeGuid)
    {
        uint sizeName = 1024;
        IntPtr pSizeName = Marshal.AllocHGlobal((int)sizeName);

        string friendlyName;

        try
        {
            PowerReadFriendlyName(IntPtr.Zero, ref schemeGuid, IntPtr.Zero, IntPtr.Zero, pSizeName, ref sizeName);
            friendlyName = Marshal.PtrToStringUni(pSizeName);
        }
        finally
        {
            Marshal.FreeHGlobal(pSizeName);
        }

        return friendlyName;
    }

    public static IEnumerable<Guid> GetAll()
    {
        var schemeGuid = Guid.Empty;

        uint sizeSchemeGuid = (uint)Marshal.SizeOf(typeof(Guid));
        uint schemeIndex = 0;

        while (PowerEnumerate(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint)AccessFlags.ACCESS_SCHEME, schemeIndex, ref schemeGuid, ref sizeSchemeGuid) == 0)
        {
            yield return schemeGuid;
            schemeIndex++;
        }
    }

    public static void Main()
    {   
        var guidPlans = GetAll();

        foreach (Guid guidPlan in guidPlans)
        {
            Console.WriteLine(ReadFriendlyName(guidPlan));
        }
    }
}

You might have to run this program as administrator for security purposes.

like image 119
Icemanind Avatar answered Sep 22 '22 20:09

Icemanind