http://www.cnblogs.com/ziwuge/archive/2011/10/04/2199141.html
注册表:
注册表中电源选项的关键字为“PowerCfg”,以为Windows XP SP3的系统为例,注册表中有“PowerCfg”的位置有①HKEY_CURRENT_USER\Control Panel\PowerCfg②HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ControlsFolder\PowerCfg③HKEY_USERS\.DEFAULT\Control Panel\PowerCfg④HKEY_USERS\S-1-5-18\Control Panel\PowerCfg⑤HKEY_USERS\S-1-5-19\Control Panel\PowerCfg⑥HKEY_USERS\S-1-5-20\Control Panel\PowerCfg⑦HKEY_USERS\S-1-5-21-1292428093-1123561945-682003330-1003\Control Panel\PowerCfg⑧HKEY_USERS\S-1-5-21-1292428093-1123561945-682003330-1003\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit。
最后通过测试分析发现电源选项中注册表①和②最为重要,①中项“PowerPolicies”为电源选项中配置的方案列表,“CurrentPowerPolicy”为当前系统使用的方案。如下:
[HKEY_CURRENT_USER\Control Panel\PowerCfg\PowerPolicies\0]
"Name"="家用/办公桌"
"Description"="此种模式适用于大多数家用和桌面计算机,这些计算机可在任何时候插入使用。"
"Policies"=hex:01,00,00,00,02,00,00,00,01,00,00,00,00,00,00,00,02,00,00,00,05,\
00,00,00,00,00,00,00,[b0,04],00,00,78,00,00,00,32,32,03,02,02,00,00,00,02,00,\
00,00,00,00,18,77,2e,f2,07,00,[3c,00],00,00,3c,00,00,00,[00,00],00,00,b4,00,00,\
00,00,00,64,64,64,64,93,7c
在Policies中存储的REG_BINARY格式(16进制格式?),分析发现第一个[]中(28/29位置,0开始)表示“系统待机”,第二个[]中(56/57位置)表示“关闭监视器”,第三个[](64/65位置)表示“关闭硬盘”。时间是按秒数的16进制保存的,比如[b0,04]表示16进制的[0x04b0],换算成十进制为1200,表示20分钟,"从不"对应的为[00,00]。
②中“PowerPolicies”和“ProcessorPolicies”列举的是出现过的电源选项(包括自定义),这里解释一下,当你通过“控制面板”→“电源选项”新建的方案这里会记录,即使你删除之后这里还是会存在(存储的数值没有分析过什麽含义:)),①的记录则会删除。“LastID”表示历史记录中出现过的方案数目,这个值和①也会有关系的。
API函数:(来源参考资料1)
Windows的电源管理可以指定多种Schemes(配置),并指定当前应用何种Scheme。对于每一种Scheme包含使用电池时的配置和使用电源时的配置。
1、枚举系统所有的Power Schemes


BOOLEAN EnumPwrSchemes( PWRSCHEMESENUMPROC lpfnPwrSchemesEnumProc, LPARAM lParam );
自定义的枚举Callback函数类型是:


Typedef BOOLEAN (CALLBACK* PWRSCHEMESENUMPROC)( UINT uiIndex, // power scheme index DWORD dwName, // size of the sName string, in bytes LPTSTR sName, // name of the power scheme DWORD dwDesc, // size of the sDesc string, in bytes LPTSTR sDesc, // description string PPOWER_POLICY pp, // receives the power policy LPARAM lParam // user-defined value );
其中:The sName and sDesc parameters are null-terminated strings; they are Unicode strings on Windows 2000/XP and ANSI strings on Windows Me/98/95.
2、得到当前正在使用的Power Scheme:


BOOLEAN GetActivePwrScheme( PUINT puiID/*得到Power Scheme索引*/ ); BOOLEAN ReadPwrScheme( UINT uiID,/*根据索引读取Scheme*/ PPOWER_POLICY pPowerPolicy );
或:


BOOLEAN GetCurrentPowerPolicies( PGLOBAL_POWER_POLICY pGlobalPowerPolicy, PPOWER_POLICY pPowerPolicy );
3、判断当前计算机是连接在电源上还是电池上:


SYSTEM_POWER_STATUS sps; GetSystemPowerStatus(&sps); if (sps.ACLineStatus) { // 连接电源 } else { // 连接电池 }
4、通过Windows的电源管理功能,我们可以得到(设定)显示器的关闭时间、硬盘停转时间、系统休眠时间。设定时间的API是:


BOOLEAN WritePwrScheme( PUINT puiID,/*Power Scheme索引*/ LPTSTR lpszName, LPTSTR lpszDescription, PPOWER_POLICY pPowerPolicy );
显示器关闭时间:POWER_POLICY.user.VideoTimeoutAc(电源)或POWER_POLICY.user.VideoTimeoutDc(电池)
硬盘停转时间:POWER_POLICY.user.SpindownTimeoutAc(电源)或POWER_POLICY.user.SpindownTimeoutDc(电池)
系统Standby和Hibernate时间稍微复杂一点,以下以连接在电源(AC)为例,得到时间的逻辑为:


if (POWER_POLICY.user.IdleAc.Action == PowerActionHibernate) { Standby 时间 = 0; Hibernate 时间 = POWER_POLICY.user.IdleTimeoutAc; } else { Standby 时间 = POWER_POLICY.user.IdleTimeoutAc; Hibernate 时间 = POWER_POLICY.user.IdleTimeoutAc+POWER_POLICY.mach.DozeS4TimeoutAc; } // 设定的逻辑为(时间值为0表示从不Standby或从不Hibernate): if (!Standby时间 && !Hibernate时间) { POWER_POLICY.user.IdleTimeoutAc = 0; POWER_POLICY.mach.DozeS4TimeoutAc = 0; POWER_POLICY.user.IdleAc.Action = PowerActionNone; } else if (Hibernate时间 && !Standby时间) { POWER_POLICY.user.IdleTimeoutAc = Hibernate时间; POWER_POLICY.mach.DozeS4TimeoutAc = 0; POWER_POLICY.user.IdleAc.Action = PowerActionHibernate; } else { POWER_POLICY.user.IdleTimeoutAc = Standby时间; POWER_POLICY.mach.DozeS4TimeoutAc = 0; if (Hibernate时间 > Standby时间) POWER_POLICY.mach.DozeS4TimeoutAc = Hibernate时间 - Standby时间; POWER_POLICY.user.IdleAc.Action = PowerActionSleep; }
5、还可以指定是否允许休眠,从待机状态中回复过来是否需要密码等
5.1、检查系统是否允许Hibernate
BOOLEAN IsPwrHibernateAllowed(void);
5.2、禁止系统Hibernate


BOOL bEnable = FALSE;
CallNtPowerInformation(SystemReserveHiberFile, &bEnable, sizeof(BOOLEAN), NULL, NULL);
这里注意:typedef BYTE BOOLEAN
5.3、允许系统Hibernate


BOOL bEnable = TRUE;
CallNtPowerInformation(SystemReserveHiberFile, &bEnable, sizeof(BOOLEAN), NULL, NULL);
还有一种最简单的办法是直接执行系统提供的程序windows\system32\powercfg.exe /hibernate {on|off}
6.还有一种更简便的方法得到(设定)系统当前的屏幕关闭时间;待机、休眠时间等,那就是调用CallNtPowerInformation:


NTSTATUS CallNtPowerInformation( POWER_INFORMATION_LEVEL InformationLevel, PVOID lpInputBuffer, ULONG nInputBufferSize, PVOID lpOutputBuffer, ULONG nOutputBufferSize );
其中InformationLevel设为SystemPowerPolicyAc(连接电源)或SystemPowerPolicyDc(使用电池)
如:
SYSTEM_POWER_POLICY spp = {0};
CallNtPowerInformation(SystemPowerPolicyAc, NULL, 0, &spp, sizeof(spp)); //get power information
//IdleTimeout:Time that the level of system activity must remain below the idle detection threshold before the system idle timer expires, in seconds.
//Idle: A POWER_ACTION_POLICY structure that defines the system power action to initiate when the system idle timer expires.
spp.IdleTimeout = ?;
//DozeS4Timeout: Time to wait between entering the suspend state and entering the hibernate sleeping state, in seconds. A value of zero indicates never hibernate.
spp.DoseS4Timeout = ?;
//SpindownTimeout:Time before power to fixed disk drives is turned off, in seconds.
spp.SpindownTimeout = ?;
//VideoTimeout:Time before the display is turned off, in seconds.
spp.VideoTimeout = ?;
CallNtPowerInformation(SystemPowerPolicyAc, &spp, sizeof(spp), NULL, 0); //set new power information
7.也可以通过WMI来设置,但需注意WMI版本是否支持:(如以下vbscript)
Set objService = GetObject("winmgmts:\\.\root\wmi")
Set objMonSet = objService.InstancesOf("WmiMonitorBrightnessMethods")
For Each objMon In objMonSet
objMon.WmiSetBrightness 10, 90
Next
8.另需注意:
调用SetActivePwrScheme()和ReadPwrScheme()时,若传递的Scheme ID不存在,则会在注册表(HKEY_CURRENT_USER\Control Panel\PowerCfg\PowerPolicies\)下创建这个ID,但内容为空,而这会导致电源管理遍历函数EnumPwrSchemes()不能正常工作(读不到该ID后的power scheme);VISTA上的对应函数(PowerGetActiveScheme/PowerReadxxx)就没发现这样的问题。
补充:
POWER_POLICY结构体的介绍http://msdn.microsoft.com/zh-cn/aa372709
POWER_POLICY结构体自己的分析:IdleTimeOut 系统待机;VideoTimeOut 关闭监视器;SpindownTimeout 关闭硬盘;AC 外接电源;DC 电池。