使用powrprof.dll
庫工作對我來說:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace Namespace {
public static class PowerOptions {
// src: https://msdn.microsoft.com/en-us/library/windows/desktop/hh448380%28v=vs.85%29.aspx
private readonly static Guid HIGH_PERFORMANCE = new Guid("8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c"); // aka MIN_POWER_SAVINGS
private readonly static Guid BALANCED = new Guid("381b4222-f694-41f0-9685-ff5bb260df2e"); // aka TYPICAL_POWER_SAVINGS
private readonly static Guid POWER_SAVER = new Guid("a1841308-3541-4fab-bc81-f71556f20b4a"); // aka MAX_POWER_SAVINGS
private readonly static Guid ACDC_POWER_SOURCE = new Guid("5d3e9a59-e9D5-4b00-a6bd-ff34ff516548");
private readonly static Guid SLEEP_SUBCATEGORY = new Guid("238C9FA8-0AAD-41ED-83F4-97BE242C8F20");
private readonly static Guid WAKE_TIMERS = new Guid("bd3b718a-0680-4d9d-8ab2-e1d2b4ac806d");
public static String GetCurrentPowerPlanFriendlyName() {
IntPtr ptrActiveGuid = IntPtr.Zero;
int ret = PowerGetActiveScheme(IntPtr.Zero, ref ptrActiveGuid);
if (ret == 0) {
uint buffSize = 0;
ret = PowerReadFriendlyName(IntPtr.Zero, ptrActiveGuid, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref buffSize);
if (ret == 0) {
if (buffSize == 0)
return "";
IntPtr ptrName = Marshal.AllocHGlobal((int) buffSize);
ret = PowerReadFriendlyName(IntPtr.Zero, ptrActiveGuid, IntPtr.Zero, IntPtr.Zero, ptrName, ref buffSize);
if (ret == 0) {
String name = Marshal.PtrToStringUni(ptrName);
Marshal.FreeHGlobal(ptrName);
return name;
}
Marshal.FreeHGlobal(ptrName);
}
}
throw new Win32Exception(ret, "GetCurrentPowerPlanFriendlyName");
}
public static PowerStatus GetPowerStatus() {
PowerStatus ps = new PowerStatus();
if (!GetSystemPowerStatus(ref ps))
throw new Win32Exception(Marshal.GetLastWin32Error(), "GetPowerStatus");
return ps;
}
public static bool GetWakeTimersEnabled(PowerSource powerSource = PowerSource.Current, PowerPlan powerPlan = PowerPlan.Current) {
int ret = 0;
if (powerSource == PowerSource.Current) {
PowerStatus ps = GetPowerStatus();
if (ps.ACLineStatus == PowerLineStatus.Online)
powerSource = PowerSource.PluggedIn;
else
powerSource = PowerSource.OnBattery;
}
if (ret == 0) {
if (powerPlan == PowerPlan.Current) {
IntPtr ptrPowerPlan = IntPtr.Zero;
ret = PowerGetActiveScheme(IntPtr.Zero, ref ptrPowerPlan);
if (ret == 0) {
uint value = 0;
if (powerSource == PowerSource.PluggedIn)
ret = PowerReadACValueIndex(IntPtr.Zero, ptrPowerPlan, SLEEP_SUBCATEGORY, WAKE_TIMERS, ref value);
else
ret = PowerReadDCValueIndex(IntPtr.Zero, ptrPowerPlan, SLEEP_SUBCATEGORY, WAKE_TIMERS, ref value);
if (ret == 0) {
return (value == 1);
}
}
}
else {
Guid guid = GetGuid(powerPlan);
uint value = 0;
if (powerSource == PowerSource.PluggedIn)
ret = PowerReadACValueIndex(IntPtr.Zero, guid, SLEEP_SUBCATEGORY, WAKE_TIMERS, ref value);
else
ret = PowerReadDCValueIndex(IntPtr.Zero, guid, SLEEP_SUBCATEGORY, WAKE_TIMERS, ref value);
if (ret == 0) {
return (value == 1);
}
}
}
throw new Win32Exception(ret, "GetWakeTimersEnabled");
}
public static Guid GetGuid(PowerPlan powerPlan) {
if (powerPlan == PowerPlan.Balanced)
return BALANCED;
if (powerPlan == PowerPlan.HighPerformance)
return HIGH_PERFORMANCE;
if (powerPlan == PowerPlan.PowerSaver)
return POWER_SAVER;
throw new ArgumentException("Not a standard power plan: " + powerPlan);
}
[DllImport("powrprof.dll", SetLastError = true)]
public static extern int PowerWriteACValueIndex(IntPtr RootPowerKey, Guid SchemeGuid, Guid SubGroupOfPowerSettingsGuid, Guid PowerSettingGuid, uint AcValueIndex);
[DllImport("powrprof.dll", SetLastError = true)]
private static extern int PowerReadACValueIndex(IntPtr RootPowerKey, IntPtr SchemeGuid, Guid SubGroupOfPowerSettingsGuid, Guid PowerSettingGuid, ref uint AcValueIndex);
[DllImport("powrprof.dll", SetLastError = true)]
private static extern int PowerReadACValueIndex(IntPtr RootPowerKey, Guid SchemeGuid, Guid SubGroupOfPowerSettingsGuid, Guid PowerSettingGuid, ref uint AcValueIndex);
[DllImport("powrprof.dll", SetLastError = true)]
private static extern int PowerReadDCValueIndex(IntPtr RootPowerKey, IntPtr SchemeGuid, Guid SubGroupOfPowerSettingsGuid, Guid PowerSettingGuid, ref uint AcValueIndex);
[DllImport("powrprof.dll", SetLastError = true)]
private static extern int PowerReadDCValueIndex(IntPtr RootPowerKey, Guid SchemeGuid, Guid SubGroupOfPowerSettingsGuid, Guid PowerSettingGuid, ref uint AcValueIndex);
[DllImport("powrprof.dll", SetLastError = true)]
private static extern int PowerGetActiveScheme(IntPtr UserRootPowerKey, ref IntPtr ActivePolicyGuid);
[DllImport("powrprof.dll", SetLastError = true)]
private static extern int PowerReadFriendlyName(IntPtr RootPowerKey, IntPtr SchemeGuid, IntPtr SubGroupOfPowerSettingsGuid, IntPtr PowerSettingGuid, IntPtr Buffer, ref uint BufferSize);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetSystemPowerStatus(ref PowerStatus lpSystemPowerStatus);
}
public enum PowerPlan {
Current,
HighPerformance,
Balanced,
PowerSaver,
}
public enum PowerSource {
Current,
OnBattery,
PluggedIn
}
public struct PowerStatus {
///<summary>The AC power status.</summary>
public PowerLineStatus ACLineStatus;
///<summary>The battery charge status.</summary>
public PowerChargeStatus BatteryFlag;
///<summary>Returns a value between [0 to 100] or 255 if unknown.</summary>
public byte BatteryLifePercent;
///<summary>Returns a value that indicates if the system is currently conserving power.</summary>
public PowerSaveStatus SystemStatusFlag;
///<summary>Number of seconds of battery life remaining, or -1 if unknown.</summary>
public int BatteryLifeTime;
///<summary>Number of seconds of batter life on a full charge, or -1 if unknown.</summary>
public int BatteryFullLifeTime;
}
public enum PowerLineStatus : byte {
Offline = 0,
Online = 1,
Unknown = 255,
}
[Flags]
public enum PowerChargeStatus : byte {
High = 1,
Low = 2,
Critical = 4,
Charging = 8,
NoBattery = 128,
Unknown = 255,
}
public enum PowerSaveStatus : byte {
Off = 0,
On = 1,
}
}
試試看。換句話說,使用'CreateWaitableTimer'來創建一個定時器並調用'SetWaitableTimer'來激活定時器'fResume'設置爲'TRUE'(並且超時設置爲遠處的某個點)。如果不支持喚醒定時器,該函數將成功,並且'GetLastError'將返回'ERROR_NOT_SUPPORTED'。用CancelWaitableTimer取消定時器。 – arx
我在Windows 8平板電腦(只有Windows 8)上嘗試了您的解決方案,並且SetWaitableTimer不返回ERROR_NOT_SUPPORTED。當我查看平板電腦上的電源選項時,喚醒計時器選項不可見。 –