|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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=====================================
|
|