我需要我的应用程序来读取系统在关闭显示器,睡觉或进入休眠状态之前等待的时间。据我所知,我需要使用电源管理功能(http://msdn.microsoft.com/en-us/library/aa373163%28v=vs.85%29.aspx)特别是,我需要使用PowerEnumerate方法(http://msdn.microsoft.com/en-us/library/aa372730%28v=vs.85%29.aspx)。
我真的很困惑如何做到这一点。首先,我在C#中这样做,代码看起来像是C ++。其次,C ++代码似乎并没有真正告诉你如何专门阅读我想要的不同时间。
注意,我是Windows编程和C#的新手。我的大部分经验都是Java和Android。
由于
答案 0 :(得分:12)
我在VB中找到了使用PowerEnumerate
函数的example on MSDN。
我已将示例转换为C#,并将友好名称添加到循环中每个视频设置的输出中。您可以将GUID_VIDEO_SUBGROUP
更改为其他子组之一以查看其他设置。
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
namespace TestProject
{
class PowerEnumerator
{
private static Guid NO_SUBGROUP_GUID = new Guid("fea3413e-7e05-4911-9a71-700331f1c294");
private static Guid GUID_DISK_SUBGROUP = new Guid("0012ee47-9041-4b5d-9b77-535fba8b1442");
private static Guid GUID_SYSTEM_BUTTON_SUBGROUP = new Guid("4f971e89-eebd-4455-a8de-9e59040e7347");
private static Guid GUID_PROCESSOR_SETTINGS_SUBGROUP = new Guid("54533251-82be-4824-96c1-47b60b740d00");
private static Guid GUID_VIDEO_SUBGROUP = new Guid("7516b95f-f776-4464-8c53-06167f40cc99");
private static Guid GUID_BATTERY_SUBGROUP = new Guid("e73a048d-bf27-4f12-9731-8b2076e8891f");
private static Guid GUID_SLEEP_SUBGROUP = new Guid("238C9FA8-0AAD-41ED-83F4-97BE242C8F20");
private static Guid GUID_PCIEXPRESS_SETTINGS_SUBGROUP = new Guid("501a4d13-42af-4429-9fd1-a8218c268e20");
[DllImport("powrprof.dll")]
static extern uint PowerEnumerate(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
ref Guid SubGroupOfPowerSetting,
uint AccessFlags,
uint Index,
ref Guid Buffer,
ref uint BufferSize);
[DllImport("powrprof.dll")]
static extern uint PowerGetActiveScheme(
IntPtr UserRootPowerKey,
ref IntPtr ActivePolicyGuid);
[DllImport("powrprof.dll")]
static extern uint PowerReadACValue(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
IntPtr SubGroupOfPowerSettingGuid,
ref Guid PowerSettingGuid,
ref int Type,
ref IntPtr Buffer,
ref uint BufferSize
);
[DllImport("powrprof.dll", CharSet = CharSet.Unicode)]
static extern uint PowerReadFriendlyName(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
IntPtr SubGroupOfPowerSettingGuid,
IntPtr PowerSettingGuid,
StringBuilder Buffer,
ref uint BufferSize
);
[DllImport("kernel32.dll")]
static extern IntPtr LocalFree(
IntPtr hMem
);
private const uint ERROR_MORE_DATA = 234;
public static void GetCurrentPowerEnumerateVistaAPI()
{
IntPtr activeGuidPtr = IntPtr.Zero;
try
{
uint res = PowerGetActiveScheme(IntPtr.Zero, ref activeGuidPtr);
if (res != 0)
throw new Win32Exception();
//Get Friendly Name
uint buffSize = 0;
StringBuilder buffer = new StringBuilder();
Guid subGroupGuid = Guid.Empty;
Guid powerSettingGuid = Guid.Empty;
res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr,
IntPtr.Zero, IntPtr.Zero, buffer, ref buffSize);
if (res == ERROR_MORE_DATA)
{
buffer.Capacity = (int)buffSize;
res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr,
IntPtr.Zero, IntPtr.Zero, buffer, ref buffSize);
}
if (res != 0)
throw new Win32Exception();
Console.WriteLine("ReadFriendlyName = " +
buffer.ToString());
//Get the Power Settings
Guid VideoSettingGuid = Guid.Empty;
uint index = 0;
uint BufferSize = Convert.ToUInt32(Marshal.SizeOf(typeof(Guid)));
while (
PowerEnumerate(IntPtr.Zero, activeGuidPtr, ref GUID_VIDEO_SUBGROUP,
18, index, ref VideoSettingGuid, ref BufferSize) == 0)
{
uint size = 4;
IntPtr temp = IntPtr.Zero;
int type = 0;
res = PowerReadACValue(IntPtr.Zero, activeGuidPtr, IntPtr.Zero,
ref VideoSettingGuid, ref type, ref temp, ref size);
IntPtr pSubGroup = Marshal.AllocHGlobal(Marshal.SizeOf(GUID_VIDEO_SUBGROUP));
Marshal.StructureToPtr(GUID_VIDEO_SUBGROUP, pSubGroup, false);
IntPtr pSetting = Marshal.AllocHGlobal(Marshal.SizeOf(VideoSettingGuid));
Marshal.StructureToPtr(VideoSettingGuid, pSetting, false);
uint builderSize = 200;
StringBuilder builder = new StringBuilder((int)builderSize);
res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr,
pSubGroup, pSetting, builder, ref builderSize);
Console.WriteLine(builder.ToString() + " = " + temp.ToString());
index++;
}
}
finally
{
if (activeGuidPtr != IntPtr.Zero)
{
IntPtr res = LocalFree(activeGuidPtr);
if (res != IntPtr.Zero)
throw new Win32Exception();
}
}
}
}
}
此代码的结果输出:
答案 1 :(得分:1)
尽管接受的答案仍然有效,但我想指出其中存在一个错误,导致它枚举了所有默认值,而不是实际值。
读取AC值时,还需要传递子组guid:
res = PowerReadACValue(IntPtr.Zero, activeGuidPtr, pSubGroup, ref settingGuid, ref type, ref temp, ref size);
答案 2 :(得分:0)
我在这篇博文中寻找类似的解决方案,并发现并纠正了一些错误。
我的IDE(Visual Studio 2019)需要一个主要功能,因此我不得不弄清楚这相当复杂的代码应该在哪里。最后,我尝试将GetCurrentPowerEnumerateVistaAPI()
重命名为Main()
。我也将@Martijn Spaan修复程序进行了少许更改。代替ref settingGuid
添加ref videoSettingGuid
。
所以现在看起来像这样,并按预期运行:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
namespace TestProject
{
class PowerEnumerator
{
private static Guid NO_SUBGROUP_GUID = new Guid("fea3413e-7e05-4911-9a71-700331f1c294");
private static Guid GUID_DISK_SUBGROUP = new Guid("0012ee47-9041-4b5d-9b77-535fba8b1442");
private static Guid GUID_SYSTEM_BUTTON_SUBGROUP = new Guid("4f971e89-eebd-4455-a8de-9e59040e7347");
private static Guid GUID_PROCESSOR_SETTINGS_SUBGROUP = new Guid("54533251-82be-4824-96c1-47b60b740d00");
private static Guid GUID_VIDEO_SUBGROUP = new Guid("7516b95f-f776-4464-8c53-06167f40cc99");
private static Guid GUID_BATTERY_SUBGROUP = new Guid("e73a048d-bf27-4f12-9731-8b2076e8891f");
private static Guid GUID_SLEEP_SUBGROUP = new Guid("238C9FA8-0AAD-41ED-83F4-97BE242C8F20");
private static Guid GUID_PCIEXPRESS_SETTINGS_SUBGROUP = new Guid("501a4d13-42af-4429-9fd1-a8218c268e20");
[DllImport("powrprof.dll")]
static extern uint PowerEnumerate(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
ref Guid SubGroupOfPowerSetting,
uint AccessFlags,
uint Index,
ref Guid Buffer,
ref uint BufferSize);
[DllImport("powrprof.dll")]
static extern uint PowerGetActiveScheme(
IntPtr UserRootPowerKey,
ref IntPtr ActivePolicyGuid);
[DllImport("powrprof.dll")]
static extern uint PowerReadACValue(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
IntPtr SubGroupOfPowerSettingGuid,
ref Guid PowerSettingGuid,
ref int Type,
ref IntPtr Buffer,
ref uint BufferSize
);
[DllImport("powrprof.dll", CharSet = CharSet.Unicode)]
static extern uint PowerReadFriendlyName(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
IntPtr SubGroupOfPowerSettingGuid,
IntPtr PowerSettingGuid,
StringBuilder Buffer,
ref uint BufferSize
);
[DllImport("kernel32.dll")]
static extern IntPtr LocalFree(
IntPtr hMem
);
private const uint ERROR_MORE_DATA = 234;
public static void Main()
//public static void GetCurrentPowerEnumerateVistaAPI()
{
IntPtr activeGuidPtr = IntPtr.Zero;
try
{
uint res = PowerGetActiveScheme(IntPtr.Zero, ref activeGuidPtr);
if (res != 0)
throw new Win32Exception();
//Get Friendly Name
uint buffSize = 0;
StringBuilder buffer = new StringBuilder();
Guid subGroupGuid = Guid.Empty;
Guid powerSettingGuid = Guid.Empty;
res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr,
IntPtr.Zero, IntPtr.Zero, buffer, ref buffSize);
if (res == ERROR_MORE_DATA)
{
buffer.Capacity = (int)buffSize;
res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr,
IntPtr.Zero, IntPtr.Zero, buffer, ref buffSize);
}
if (res != 0)
throw new Win32Exception();
Console.WriteLine("ReadFriendlyName = " +
buffer.ToString());
//Get the Power Settings
Guid VideoSettingGuid = Guid.Empty;
uint index = 0;
uint BufferSize = Convert.ToUInt32(Marshal.SizeOf(typeof(Guid)));
while (
PowerEnumerate(IntPtr.Zero, activeGuidPtr, ref GUID_VIDEO_SUBGROUP,
18, index, ref VideoSettingGuid, ref BufferSize) == 0)
{
uint size = 4;
IntPtr temp = IntPtr.Zero;
int type = 0;
// My chenges
IntPtr pSubGroup = Marshal.AllocHGlobal(Marshal.SizeOf(GUID_VIDEO_SUBGROUP));
res = PowerReadACValue(IntPtr.Zero, activeGuidPtr, pSubGroup, ref VideoSettingGuid, ref type, ref temp, ref size);
// end my changes
Marshal.StructureToPtr(GUID_VIDEO_SUBGROUP, pSubGroup, false);
IntPtr pSetting = Marshal.AllocHGlobal(Marshal.SizeOf(VideoSettingGuid));
Marshal.StructureToPtr(VideoSettingGuid, pSetting, false);
uint builderSize = 200;
StringBuilder builder = new StringBuilder((int)builderSize);
res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr,
pSubGroup, pSetting, builder, ref builderSize);
Console.WriteLine(builder.ToString() + " = " + temp.ToString());
index++;
}
}
finally
{
if (activeGuidPtr != IntPtr.Zero)
{
IntPtr res = LocalFree(activeGuidPtr);
if (res != IntPtr.Zero)
throw new Win32Exception();
}
}
Console.ReadLine();
}
}
}