WinOS下的电源计划设置

在 Windows OS 下电源高级选项中的电源管理计划是按照如下几组 GUID 来进行分类设置的:

  1. PowerActiveScheme GUID
  2. SubGroup GUID
  3. PowerSettingItem GUID

在程序中需要获取或者修改电源计划时,需要使用以上的三个GUID 标识符,各项GUID标识符及计划分组的获取可以通过cmd命令powercfg /Q来获取


一、获取电源计划的值

主要分为 AC、DC 模式下的对应值,流程如下:

  1. powrprof.dll 中导入对应的Win32API
  2. 获取当前的电源计划,及对应的 GUID标识符,如:PowerActiveScheme
  3. 获取对应模式下,对应条目下的具体项值:如:SbuGroup-->PowerSettingItem-->CustomSettingValue
private static Guid GUID_SLEEP_SUBGROUP = new Guid("238c9fa8-0aad-41ed-83f4-97be242c8f20"); //SubGroup: Sleep
private static Guid GUID_STANDBYIDLE = new Guid("29f6c1db-86da-48c5-9fdb-f2b67b1f44da");   
 //Items: Sleep State
private static Guid GUID_HIBERNATEIDLE = new Guid("9d7815a6-7ee4-497e-8888-515a05f02364"); 
 //Items: Hibernate State

[DllImport("powrprof.dll")]
static extern uint PowerGetActiveScheme(IntPtr UserRootPowerKey, ref IntPtr ActivePolicyGuid);
[DllImport("powrprof.dll")]
static extern uint PowerReadACValue(
    IntPtr RootPowerKey,
    ref Guid SchemeGuid,
    ref Guid SubGroupOfPowerSettingGuid,
    ref Guid PowerSettingGuid,
    ref int Type,
    ref int Buffer,
    ref uint BufferSize);

// 获取接电源时,多久进入睡眠(ModernStandby)的时间,单位秒,0表示永不睡眠
public static int GetACSleepTimeOut()
{
    IntPtr activePolicyGuidPTR = IntPtr.Zero;
    uint i = PowerGetActiveScheme(IntPtr.Zero, ref activePolicyGuidPTR);

    Guid activePolicyGuid = Marshal.PtrToStructure<Guid>(activePolicyGuidPTR);
    int type = 0;
    int value = 0;
    uint valueSize = 4u;
    // 使用电池时,则对应于 PowerReadDCValue 
    uint errorRes = PowerReadACValue(IntPtr.Zero,
        ref activePolicyGuid,
        ref GUID_SLEEP_SUBGROUP,
        ref GUID_STANDBYIDLE,
        ref type,
        ref value,
        ref valueSize);

    if (errorRes != 0)
    {
        Console.WriteLine("Read AC Sleep Time failed.");
    }

    return value;
}


二、修改电源计划的值

与获取电源计划的值类似,

  1. powrprof.dll 中导入对应的Win32API
  2. 获取当前的电源计划,及对应的 GUID标识符
  3. 设置对应模式下,对应条目下的具体项值
private static Guid GUID_VIDEO_SUBGROUP = new Guid("7516b95f-f776-4464-8c53-06167f40cc99"); // SubGroup: Display settings
private static Guid GUID_VIDEOIDLE = new Guid("3c0bc021-c8a8-4e07-a973-6b14cbcb2b7e");  // Screen display turn off.

[DllImport("powrprof.dll")]
static extern uint PowerGetActiveScheme(IntPtr UserRootPowerKey, ref IntPtr ActivePolicyGuid);
[DllImport("powrprof.dll")]
static extern uint PowerWriteACValueIndex(
    IntPtr RootPowerKey,
    ref Guid SchemeGuid,
    ref Guid SubGroupOfPowerSettingGuid,
    ref Guid PowerSettingGuid,
    int AcValueIndex);

[DllImport("powrprof.dll")]
static extern uint PowerSetActiveScheme(IntPtr UserRootPowerKey, ref Guid powerSchemeGuid);

// 设置多久后屏幕关闭
public static void SetScreenOffACTime(int seconds)
{
    // 1. Get the current active power scheme and a GUID that identifies the scheme.
    IntPtr powerSchemeGuidPTR = IntPtr.Zero;
    uint errorCode_1 = PowerGetActiveScheme(IntPtr.Zero, ref powerSchemeGuidPTR);
    if (errorCode_1 != 0)
        return;
    Guid powerSchemeGuid = Marshal.PtrToStructure<Guid>(powerSchemeGuidPTR);

    // 2. Set the value for the specified power setting.
    uint errorCode_2 = PowerWriteACValueIndex(IntPtr.Zero,
        ref powerSchemeGuid,
        ref GUID_VIDEO_SUBGROUP,
        ref GUID_VIDEOIDLE,
        seconds);

    if (errorCode_2 == 0)
        PowerSetActiveScheme(IntPtr.Zero, ref powerSchemeGuid); // 必须要调用PowerSetActiveScheme,才能使修改生效
}



【参考资料】

  1. Power button and lid settings overview
  2. PowerWriteACValueIndex function
  3. PowerGetActiveScheme function
  4. Powercfg command-line options
posted @ 2022-09-19 15:47  Jeffxue  阅读(424)  评论(0编辑  收藏  举报