马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 username_badboy 于 2012-12-12 08:42 编辑
近段时间开始学习VC编程,从今天开始会坚持将自己的学习笔记记录下来和大家一起分享,希望和大家一起共同进步!我相信分享即是快乐,能帮到别人是你价值的体现(最近才悟到的)。
下面进入正题,我今天学习了使用C++调用api实现计算机的重启、关机等功能,我会附上源码并大致的讲解一下程序的主要代码,首先要介绍一个非常非常用的api函数WinMain函数:应用程序入口
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance 当前程序实例句柄
HINSTANCE hPrevInstance, // handle to previous instance 上一个程序实例句柄(在NT以后就没有用了,只是为了兼容以前的程序)
LPSTR lpCmdLine, // pointer to command line 运行时传入的参数
int nCmdShow // show state of window 以哪种方式显示窗口
);
第二个函数是真正实现功能的函数ExitWindowsEx://退出程序,包括关机、注销、重启
BOOL ExitWindowsEx(
UINT uFlags, // shutdown operation
DWORD dwReserved // reserved
);
uFlags参数的一些取值:
EWX_LOGOFF:注销
EWX_REBOOT:重启
EWX_SHUTDOWN:关机
还可以加上下面的一个参数(取或运算):
EWX_FORCE:强制结束
EWX_FORCEIFHUNG:通知其他程序准备退出
dwReserved参数是关机的原因(这个参数是可以忽略的):
SHTDN_RESON_MAJOR_APPLICATION 应用程序原因等等..
还会使用到一个获取当前系统版本的函数GetVersionEx:BOOL GetVersionEx(
LPOSVERSIONINFO lpVersionInformation // pointer to version
// information structure
);
//旧版本(新版本OSVERSIONINFOEX与这个类似)
typedef struct _OSVERSIONINFO{
DWORD dwOSVersionInfoSize;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
DWORD dwBuildNumber;
DWORD dwPlatformId; //我们这儿用到的只是这个值,平台ID
TCHAR szCSDVersion[ 128 ];
} OSVERSIONINFO;
dwPlatformId的值有:
VER_PLATFORM_WIN32_WINDOWS //windows 95 or windows 98
VER_PLATFORM_WIN32_NT // windows NT xp 2000 ...
如果是NT以后的系统就需要提升权限了(不会让你乱来的!),提升权限也就是程序实现代码中的nableShutDownPriv()函数,这个函数是比较固定的,一般只需要修改一个地方,我在代码中有注明,这儿就不多说了,如果想对这个函数里的api函数深入了解的话,可以查查MSDN,也可以看看这篇文章http://zhidao.baidu.com/question/44997791.html。
由于时间关系,代码讲解就到这里了,如果有不明白的地方可以查查MSDN或找我交流。到这里就可以测试程序了,最好是编译的时候选择release(发布)版本,不然可能会放到另外的电脑上就不能执行,还有就是最好在虚拟机上测试,因为它真的会不问问你就执行的哦。执行的时候可以使用两种方式,第一种是cmd的方式,因为要给它传参数, 还有一种就是创建快捷方式然后在快捷方式上-->右键-->属性-->目标-->在目标字符串中加参数,然后双击能执行了。累死我了,希望对大家有帮助,后边是源代码。#include <tchar.h>
#include <WINDOWS.H>
//为当前程序提升权限,这个函数比较固定,一般只用修改LookupPrivilegeValue中的第二个参数
BOOL EnableShutDownPriv()
{
//存放访问令牌句柄
HANDLE hToken = NULL;
TOKEN_PRIVILEGES tkp;
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken))
{
return false;
}
//一般只需改SE_SHUTDOWN_NAME的值
if (!LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid))
{
CloseHandle(hToken);
return false;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken,false,&tkp,sizeof(TOKEN_ADJUST_PRIVILEGES),NULL,NULL))
{
CloseHandle(hToken);
return false;
}
return true;
}
/*
*dwFlags:执行操作类型
*bForce:是否强制执行
*/
BOOL ReSetWindows(DWORD dwFlags,BOOL bForce)
{
//检验参数是否合法
if(dwFlags != EWX_LOGOFF && dwFlags != EWX_REBOOT && EWX_SHUTDOWN)
{
return false;
}
//存放返回值的结构
OSVERSIONINFO ovsi;
//这一步必不可少
ovsi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
//获取系统版本号
if (!GetVersionEx(&ovsi))
{
return false;
}
//判断是不是NT系统
if (ovsi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
//提升权限
EnableShutDownPriv();
}
dwFlags |=bForce?EWX_FORCE:EWX_SHUTDOWN;//三元表达式
//执行相应操作
return ExitWindowsEx(dwFlags,0);
}
int WINAPI WinMain(
HINSTANCE hInstance, // 当前程序实例句柄
HINSTANCE hPrevInstance, //上一个程序实例句柄(在NT以后就没有用了,只是为了兼容以前的程序)
LPSTR lpCmdLine, // 运行时传入的参数
int nCmdShow // 以哪种方式显示窗口
)
{
//_tcscmp函数作用是判断两个字串是否相等
if (_tcscmp(lpCmdLine,_T("/r")) == 0)
{
ReSetWindows(EWX_REBOOT,false);
}else if (_tcscmp(lpCmdLine,_T("/s")) == 0)
{
ReSetWindows(EWX_SHUTDOWN,false);
}else if (_tcscmp(lpCmdLine,_T("/l")) == 0)
{
ReSetWindows(EWX_LOGOFF,false);
}else
{
MessageBox(NULL,"请传入正确的参数! /r:重启 /s:关机 /l:注销","提示",NULL);
}
return 0;
}
===================================END=====================================
|