返回

如何获取 Windows 电源计划信息?使用 WinAPI 全面解析

windows

获取 Windows 电源计划/方案:使用 WinAPI

简介

在计算机系统中,电源计划是用户定义的设置集合,它们影响计算机的功耗和性能。在某些情况下,你可能需要获取系统中所有电源计划的列表,例如进行诊断或管理目的。本文将指导你使用 Windows API(WinAPI)通过 C# 枚举所有电源计划,包括它们的 GUID 和用户友好名称。

枚举电源计划

要枚举所有电源计划,你需要调用 WinAPI 函数 PowerEnumerate。此函数需要以下参数:

  • RootPowerKey: 指定要枚举的根键。通常传递 IntPtr.Zero 来枚举所有电源计划。
  • SchemeGuid: 指定要筛选的特定电源计划 GUID。传递 IntPtr.Zero 来枚举所有电源计划。
  • AccessFlags: 指定访问权限。使用 POWER_DATA_ACCESSOR_ACCESS_SCHEME

访问电源计划详细信息

枚举所有电源计划后,你可以使用 PowerReadFriendlyName 函数访问每个电源计划的详细信息,例如其友好名称。此函数需要以下参数:

  • SchemeGuid: 要获取友好名称的电源计划 GUID。

代码示例

以下代码示例演示如何在 C# 中使用 WinAPI 枚举所有电源计划,包括它们的 GUID 和用户友好名称:

using System;
using System.Runtime.InteropServices;

namespace PowerPlans
{
    class Program
    {
        const uint POWER_DATA_ACCESSOR_ACCESS_SCHEME = 0x00000001;

        [DllImport("powrprof.dll", SetLastError = true)]
        static extern uint PowerEnumerate(IntPtr RootPowerKey, IntPtr SchemeGuid, IntPtr SubGroupOfPowerSettingsGuid, uint AccessFlags, uint Index, byte[] Buffer, ref uint BufferSize);

        [DllImport("powrprof.dll", SetLastError = true)]
        static extern uint PowerReadFriendlyName(Guid SchemeGuid, IntPtr Buffer, ref uint BufferSize);

        static void Main(string[] args)
        {
            uint bufferSize = 0;
            uint result = PowerEnumerate(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, POWER_DATA_ACCESSOR_ACCESS_SCHEME, 0, null, ref bufferSize);

            if (result == 0)
            {
                throw new InvalidOperationException("Error enumerating power plans.");
            }

            byte[] buffer = new byte[bufferSize];
            result = PowerEnumerate(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, POWER_DATA_ACCESSOR_ACCESS_SCHEME, 0, buffer, ref bufferSize);

            if (result != 0)
            {
                int offset = 0;

                while (offset < bufferSize)
                {
                    var scheme = Marshal.PtrToStructure<POWER_SCHEME_INFO>(new IntPtr(buffer, offset));

                    // 获取电源计划的 GUID
                    Guid guid = scheme.PowerSchemeGuid;

                    // 获取电源计划的用户友好名称
                    string name = GetPowerPlanFriendlyName(guid);

                    // 处理电源计划
                    Console.WriteLine(
using System;
using System.Runtime.InteropServices;

namespace PowerPlans
{
    class Program
    {
        const uint POWER_DATA_ACCESSOR_ACCESS_SCHEME = 0x00000001;

        [DllImport("powrprof.dll", SetLastError = true)]
        static extern uint PowerEnumerate(IntPtr RootPowerKey, IntPtr SchemeGuid, IntPtr SubGroupOfPowerSettingsGuid, uint AccessFlags, uint Index, byte[] Buffer, ref uint BufferSize);

        [DllImport("powrprof.dll", SetLastError = true)]
        static extern uint PowerReadFriendlyName(Guid SchemeGuid, IntPtr Buffer, ref uint BufferSize);

        static void Main(string[] args)
        {
            uint bufferSize = 0;
            uint result = PowerEnumerate(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, POWER_DATA_ACCESSOR_ACCESS_SCHEME, 0, null, ref bufferSize);

            if (result == 0)
            {
                throw new InvalidOperationException("Error enumerating power plans.");
            }

            byte[] buffer = new byte[bufferSize];
            result = PowerEnumerate(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, POWER_DATA_ACCESSOR_ACCESS_SCHEME, 0, buffer, ref bufferSize);

            if (result != 0)
            {
                int offset = 0;

                while (offset < bufferSize)
                {
                    var scheme = Marshal.PtrToStructure<POWER_SCHEME_INFO>(new IntPtr(buffer, offset));

                    // 获取电源计划的 GUID
                    Guid guid = scheme.PowerSchemeGuid;

                    // 获取电源计划的用户友好名称
                    string name = GetPowerPlanFriendlyName(guid);

                    // 处理电源计划
                    Console.WriteLine($"GUID: {guid}");
                    Console.WriteLine($"Name: {name}");

                    offset += scheme.Length;
                }
            }
        }

        static string GetPowerPlanFriendlyName(Guid schemeGuid)
        {
            uint bufferSize = 0;
            uint result = PowerReadFriendlyName(schemeGuid, IntPtr.Zero, ref bufferSize);

            if (result == 0)
            {
                throw new InvalidOperationException("Error getting power plan friendly name.");
            }

            byte[] buffer = new byte[bufferSize];
            result = PowerReadFriendlyName(schemeGuid, new IntPtr(buffer, 0), ref bufferSize);

            if (result != 0)
            {
                return Marshal.PtrToStringUni(new IntPtr(buffer, 0));
            }

            return null;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    struct POWER_SCHEME_INFO
    {
        public Guid PowerSchemeGuid;
        public uint Flags;
        public uint AccessFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string FriendlyName;
        public uint Length;
    }
}
quot;GUID: {guid}"
); Console.WriteLine(
using System;
using System.Runtime.InteropServices;

namespace PowerPlans
{
    class Program
    {
        const uint POWER_DATA_ACCESSOR_ACCESS_SCHEME = 0x00000001;

        [DllImport("powrprof.dll", SetLastError = true)]
        static extern uint PowerEnumerate(IntPtr RootPowerKey, IntPtr SchemeGuid, IntPtr SubGroupOfPowerSettingsGuid, uint AccessFlags, uint Index, byte[] Buffer, ref uint BufferSize);

        [DllImport("powrprof.dll", SetLastError = true)]
        static extern uint PowerReadFriendlyName(Guid SchemeGuid, IntPtr Buffer, ref uint BufferSize);

        static void Main(string[] args)
        {
            uint bufferSize = 0;
            uint result = PowerEnumerate(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, POWER_DATA_ACCESSOR_ACCESS_SCHEME, 0, null, ref bufferSize);

            if (result == 0)
            {
                throw new InvalidOperationException("Error enumerating power plans.");
            }

            byte[] buffer = new byte[bufferSize];
            result = PowerEnumerate(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, POWER_DATA_ACCESSOR_ACCESS_SCHEME, 0, buffer, ref bufferSize);

            if (result != 0)
            {
                int offset = 0;

                while (offset < bufferSize)
                {
                    var scheme = Marshal.PtrToStructure<POWER_SCHEME_INFO>(new IntPtr(buffer, offset));

                    // 获取电源计划的 GUID
                    Guid guid = scheme.PowerSchemeGuid;

                    // 获取电源计划的用户友好名称
                    string name = GetPowerPlanFriendlyName(guid);

                    // 处理电源计划
                    Console.WriteLine($"GUID: {guid}");
                    Console.WriteLine($"Name: {name}");

                    offset += scheme.Length;
                }
            }
        }

        static string GetPowerPlanFriendlyName(Guid schemeGuid)
        {
            uint bufferSize = 0;
            uint result = PowerReadFriendlyName(schemeGuid, IntPtr.Zero, ref bufferSize);

            if (result == 0)
            {
                throw new InvalidOperationException("Error getting power plan friendly name.");
            }

            byte[] buffer = new byte[bufferSize];
            result = PowerReadFriendlyName(schemeGuid, new IntPtr(buffer, 0), ref bufferSize);

            if (result != 0)
            {
                return Marshal.PtrToStringUni(new IntPtr(buffer, 0));
            }

            return null;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    struct POWER_SCHEME_INFO
    {
        public Guid PowerSchemeGuid;
        public uint Flags;
        public uint AccessFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string FriendlyName;
        public uint Length;
    }
}
quot;Name: {name}"
); offset += scheme.Length; } } } static string GetPowerPlanFriendlyName(Guid schemeGuid) { uint bufferSize = 0; uint result = PowerReadFriendlyName(schemeGuid, IntPtr.Zero, ref bufferSize); if (result == 0) { throw new InvalidOperationException("Error getting power plan friendly name."); } byte[] buffer = new byte[bufferSize]; result = PowerReadFriendlyName(schemeGuid, new IntPtr(buffer, 0), ref bufferSize); if (result != 0) { return Marshal.PtrToStringUni(new IntPtr(buffer, 0)); } return null; } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] struct POWER_SCHEME_INFO { public Guid PowerSchemeGuid; public uint Flags; public uint AccessFlags; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string FriendlyName; public uint Length; } }

结论

通过使用 WinAPI 和 C#,你可以轻松枚举所有 Windows 电源计划,包括它们的 GUID 和用户友好名称。这对于管理和诊断计算机功耗和性能很有用。

常见问题解答

  1. 如何只获取特定电源计划?
    你可以在 PowerEnumerate 函数中指定 SchemeGuid 参数来筛选特定电源计划。

  2. 如何更新电源计划的设置?
    你可以使用 PowerSetActiveScheme 函数更新电源计划的设置。

  3. 如何创建新的电源计划?
    你可以使用 PowerCreateScheme 函数创建新的电源计划。

  4. 如何删除电源计划?
    你可以使用 PowerDeleteScheme 函数删除电源计划。

  5. 如何设置默认电源计划?
    你可以使用 PowerSetDefaultScheme 函数设置默认电源计划。