最近因为项目原因,需要控制操作系统的电源,也就是令操作系统何时关闭显示器、何时关闭硬盘、何时待机、何时休眠等。
这个可以使用API控制,我这里采用的是控制操作系统的电源方案,可以通过命令行中的powercfg去控制。控制操作系统的电源方案,还是调用API函数。
下面我就分别说一下windows xp和windows 7下电源操作的方法,这里以控制操作系统的电源方案为例。
我在项目中是先创建一个C的DLL,需引用PowrProf.lib静态库。
详细API操作请参见:http://msdn.microsoft.com/en-us/library/aa372711(v=VS.85).aspx
1、Windows Xp电源方案控制
XP下的电源方案,如下图:
上图中的“家用”、“便携" 、”演示“、”一直开碰上“、”最少电源管理“、”最大电模式“是系统自带的五种方案,其索引值分别以0--4表示,其相应信息存储在注册表中。
创建电源方案,先使用"ReadPwrScheme"读取一个原有方案,然后在获取到的对象中设置自己的设置值,再使用 "WritePwrScheme”添加该方案,最后使用"SetActivePwrScheme“激活该电源方案,使我们自己填加的电源方案为正在使用的电源方案。
我正在使用的源码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
2 /* 设置方案值与名称 */
3 extern " C " __declspec(dllexport) BOOLEAN WriteSchemeForXP(LPCWSTR lpszSchemeName,LPCWSTR lpszSchemeDescription,ULONG a,ULONG b,ULONG c,ULONG d,ULONG e,ULONG f,ULONG g,ULONG h)
4 {
5 UINT id = 100 ;
6 // create
7 PPOWER_POLICY policy = new POWER_POLICY();
8 // read
9 ReadPwrScheme( 0 ,policy);
10 // write
11 policy -> user.IdleTimeoutAc = e; // 待机
12 policy -> user.IdleTimeoutDc = f;
13 policy -> user.SpindownTimeoutAc = c; // 关闭硬盘
14 policy -> user.SpindownTimeoutDc = d;
15 policy -> user.VideoTimeoutAc = a; // 关闭显示器
16 policy -> user.VideoTimeoutDc = b;
17 policy -> mach.DozeS4TimeoutAc = g; // 休眠
18 policy -> mach.DozeS4TimeoutDc = h;
19
20 BOOLEAN result = WritePwrScheme( & id,lpszSchemeName,lpszSchemeDescription,policy);
21 SetActivePwrScheme( 100 , 0 , 0 );
22 return result;
23 }
24
25 /* 删除电源方案 */
26 extern " C " __declspec(dllexport) BOOLEAN DelSchemeForXP()
27 {
28 // delete
29 BOOLEAN result = DeletePwrScheme( 100 );
30 // active
31 SetActivePwrScheme( 0 , 0 , 0 );
32 return result;
33 return 0 ;
34 }
2、Windows 7下的电源方案
Windows7与XP不同,它使用GUID值来唯一标识电源方案及电源方案下的各个详细信息,并且Windows7可以设置更加详细的电源控制,可以从powercfg /query中查看。
原理与XP相同,源码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
{ 0x3b662acb , 0x0e27 , 0x40cd , { 0x87 , 0x1d , 0xd1 , 0xb5 , 0xc1 , 0xac , 0x3e , 0xfe } };
static GUID * MAKE_GUID = new GUID(GLOBAL_GUID);
// 电源方案"平衡"的GUID值 for WIN7
static const GUID POWER_SAVER_GUID = {
0x381b4222 , 0xf694 , 0x41f0 ,{ 0x96 , 0x85 , 0xff , 0x5b , 0xb2 , 0x60 , 0xdf , 0x2e }
};
// 电源GUID定义
// 显示子组GUID
static const GUID MONITOR_GROUP_GUID = {
0x7516b95f , 0xf776 , 0x4464 ,{ 0x8c , 0x53 , 0x06 , 0x16 , 0x7f , 0x40 , 0xcc , 0x99 }
};
// 显示子组子项GUID
static const GUID MONTOR_GROUP_SUB_ID =
{
0x3c0bc021 , 0xc8a8 , 0x4e07 ,{ 0xa9 , 0x73 , 0x6b , 0x14 , 0xcb , 0xcb , 0x2b , 0x7e }
};
// 硬盘组
static const GUID HARD_DISK_GROUP_GUID = {
0x0012ee47 , 0x9041 , 0x4b5d ,{ 0x9b , 0x77 , 0x53 , 0x5f , 0xba , 0x8b , 0x14 , 0x42 }
};
// 硬盘子组GUID
static const GUID HARD_DISK_SUB_GUID = {
0x6738e2c4 , 0xe8a5 , 0x4a42 ,{ 0xb1 , 0x6a , 0xe0 , 0x40 , 0xe7 , 0x69 , 0x75 , 0x6e }
};
// 睡眠组
static const GUID SLEEP_GROUP_GUID =
{
0x238c9fa8 , 0x0aad , 0x41ed ,{ 0x83 , 0xf4 , 0x97 , 0xbe , 0x24 , 0x2c , 0x8f , 0x20 }
};
// 睡眠组睡眠子组GUID
static const GUID SLEEP_SUB_GUID =
{
0x29f6c1db , 0x86da , 0x48c5 ,{ 0x9f , 0xdb , 0xf2 , 0xb6 , 0x7b , 0x1f , 0x44 , 0xda }
};
// 睡眠组待机子组GUID
static const GUID SLEEP_SUB_HIBERNATE_GUID =
{
0x9d7815a6 , 0x7ee4 , 0x497e ,{ 0x88 , 0x88 , 0x51 , 0x5a , 0x05 , 0xf0 , 0x23 , 0x64 }
};
/* 电源操作 for windows 7 */
/* 设置方案值与名称 */
extern " C " __declspec(dllexport) BOOLEAN WriteSchemeFor7(LPCWSTR lpszSchemeName,LPCWSTR lpszSchemeDescription,ULONG a,ULONG b,ULONG c,ULONG d,ULONG e,ULONG f,ULONG g,ULONG h)
{
// 检查活动GUID
GUID * activeGuid = NULL;
PowerGetActiveScheme(NULL, & activeGuid);
BOOLEAN check = TRUE;
// 检测GUID是否相等
if (activeGuid -> Data1 == MAKE_GUID -> Data1 && activeGuid -> Data2 == MAKE_GUID -> Data2 && activeGuid -> Data3 ==
MAKE_GUID -> Data3)
{
for ( int i = 0 ; i < 8 ;i ++ )
{
if (activeGuid -> Data4[i] != MAKE_GUID -> Data4[i])
{
check = FALSE;
break ;
}
}
}
else
{
check = FALSE;
}
// 如果当前活动不是预定义方案,删除
if ( ! check)
{
PowerDeleteScheme(NULL,MAKE_GUID);
PowerDuplicateScheme(NULL, & POWER_SAVER_GUID, & MAKE_GUID);
}
DWORD bufferSize = strlen(( char * )lpszSchemeName);
int result = 0 ;
if (bufferSize % 2 != 0 )
bufferSize += 1 ;
// 修改名称及说明
PowerWriteFriendlyName(NULL,MAKE_GUID,NULL,NULL,(UCHAR * )lpszSchemeName,bufferSize);
bufferSize = strlen(( char * )lpszSchemeDescription);
if (bufferSize % 2 != 0 )
bufferSize += 1 ;
PowerWriteDescription(NULL,MAKE_GUID,NULL,NULL,(UCHAR * )lpszSchemeDescription,bufferSize);
// 显示器
PowerWriteACValueIndex(NULL,MAKE_GUID, & MONITOR_GROUP_GUID, & MONTOR_GROUP_SUB_ID,a);
PowerWriteDCValueIndex(NULL,MAKE_GUID, & MONITOR_GROUP_GUID, & MONTOR_GROUP_SUB_ID,b);
// 硬盘
PowerWriteACValueIndex(NULL,MAKE_GUID, & HARD_DISK_GROUP_GUID, & HARD_DISK_SUB_GUID,c);
PowerWriteDCValueIndex(NULL,MAKE_GUID, & HARD_DISK_GROUP_GUID, & HARD_DISK_SUB_GUID,d);
// 睡眠
PowerWriteACValueIndex(NULL,MAKE_GUID, & SLEEP_GROUP_GUID, & SLEEP_SUB_GUID,e);
PowerWriteDCValueIndex(NULL,MAKE_GUID, & SLEEP_GROUP_GUID, & SLEEP_SUB_GUID,f);
// 待机
PowerWriteACValueIndex(NULL,MAKE_GUID, & SLEEP_GROUP_GUID, & SLEEP_SUB_HIBERNATE_GUID,g);
PowerWriteDCValueIndex(NULL,MAKE_GUID, & SLEEP_GROUP_GUID, & SLEEP_SUB_HIBERNATE_GUID,h);
// 激活
PowerSetActiveScheme(NULL,MAKE_GUID);
return result;
}
/* 删除电源方案 */
extern " C " __declspec(dllexport) BOOLEAN DelSchemeFor7()
{
// active
PowerSetActiveScheme(NULL, & POWER_SAVER_GUID);
// delete
BOOLEAN result = PowerDeleteScheme(NULL,MAKE_GUID);
return result;
}
总体来说,对XP及WIN7的电源控制,从电源方案入手是比较简单的,还有另一种方法,就是使用命令powercf控制。