Получить планы/схемы электропитания Windows на C# (используя WinAPI)

Я заинтересован в том, чтобы получить все планы питания, которые есть на вашем компьютере, с помощью C#.

Я подумал, что вы могли бы использовать API PowerEnumerate каким-то образом:

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
);

Но я понятия не имею, как это сделать, так как я действительно не знаю C. Итак ... Как я могу перечислить все доступные планы электропитания и создать их список. Затем я хочу иметь доступ к каждому GUID плана питания и их «удобному имени».

Итак... Возможно, если кто-то, кто умеет использовать WinAPI из C#, захочет помочь, это было бы здорово - или если у кого-то есть лучшее решение. Я действительно пытался найти хороший ответ на этот вопрос, но, похоже, его нет. Я думаю, что это помогло бы многим людям.

Может кто-нибудь помочь с этим?


person hsson    schedule 09.10.2014    source источник


Ответы (1)


Это должно сделать это:

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));
        }
    }
}

Возможно, вам придется запустить эту программу от имени администратора в целях безопасности.

person Icemanind    schedule 09.10.2014
comment
Работает так, как я хотел! Большое спасибо!! Если у вас есть время, было бы неплохо, если бы вы могли дать ссылку на какой-нибудь учебник, где я мог бы научиться делать такие вещи самостоятельно. Еще раз спасибо! - person hsson; 10.10.2014