返回
如何获取 Windows 电源计划信息?使用 WinAPI 全面解析
windows
2024-03-21 17:59:36
获取 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 和用户友好名称。这对于管理和诊断计算机功耗和性能很有用。
常见问题解答
-
如何只获取特定电源计划?
你可以在PowerEnumerate
函数中指定SchemeGuid
参数来筛选特定电源计划。 -
如何更新电源计划的设置?
你可以使用PowerSetActiveScheme
函数更新电源计划的设置。 -
如何创建新的电源计划?
你可以使用PowerCreateScheme
函数创建新的电源计划。 -
如何删除电源计划?
你可以使用PowerDeleteScheme
函数删除电源计划。 -
如何设置默认电源计划?
你可以使用PowerSetDefaultScheme
函数设置默认电源计划。