实现这一功能很简单,主要需要调用一个系统API

ExitWindowsEx

功能就是,注销当前用户,关闭系统,或者重新启动系统。

它会发送一个WM_QUERYENDSESSION消息给所有的应用程序,让他们决定是不是可以被关闭。

函数原型:

  1. <span style="font-size:18px;">BOOL WINAPI ExitWindowsEx(
  2. __in UINT uFlags,
  3. __in DWORD dwReason
  4. );
  5. </span>
第一个参数是关闭类型,第二个是关闭的原因

第一个参数可以是:

EWX_LOGOFF
0

EWX_POWEROFF
0x00000008

EWX_REBOOT
0x00000002

EWX_RESTARTAPPS
0x00000040

EWX_SHUTDOWN
0x00000001

这个参数还可以可选的包含下面两个值

EWX_FORCE
0x00000004       包含这个参数可以让系统强制关机,可能会让应用程序丢失数据

EWX_FORCEIFHUNG
0x00000010

如果在超时时间以后应用进程仍然没有响应WM_QUERYENDSESSION或WM_ENDSESSION消息,那么就强制关闭它们。

返回值:

成功的话返回非0值,失败返回0

可以通过GetLastError()获得更多错误信息。

除了了解这个函数以外,我们还应该清楚:

对于windows NT以上版本的操作系统,我们需要提升一个SE_SHUTDOWN权限,才能完成关机的操作。

NT一下的则不需要,例如95,98,ME

NT以上的系统包括:

Microsoft Windows 2000 (Windows NT 5.0) (1999) (2000-2010) 
Microsoft Windows XP (Windows NT 5.1) (2001-2014) 
Microsoft Windows Server 2003 (Windows NT 5.2) (2003-2015) 
Microsoft Windows Server 2003 R2 (Windows NT 5.2) (2006-2015) 
Microsoft Windows Vista (Windows NT 6.0) (2006-2017) 
Microsoft Windows Server 2008 (Windows NT 6.0) (2008-2018) 
Microsoft Windows 7 (Windows NT 6.1) (2009-2020) 

下面我们开始具体实现:

关机功能实现

1.检查系统版本,看是不是NT以上,如果是则要提升权限

2.调用系统API,ExitWindowsEx。

  1. #pragma region 功能实现
  2. BOOL ReSetWindows(DWORD dwFlags,BOOL bForce)
  3. {
  4. //检查参数是否正确
  5. if(dwFlags!=EWX_LOGOFF&&dwFlags!=EWX_REBOOT&&dwFlags!=EWX_SHUTDOWN)
  6. return FALSE;
  7. //获得系统的版本信息,让我们后面确定是否需要提升系统权限
  8. OSVERSIONINFO osvi={0};
  9. //获得参数的大小,以提供给GetVersionEx来判断这是一个新版本的OSVERSIONINFO,还是旧版本的
  10. //新版本是OSVERSIONINFOEX。扩充版本
  11. osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
  12. if(!GetVersionEx(&osvi))
  13. {
  14. return FALSE;
  15. }
  16. //检查操作系统的版本,如果是NT类型的系统,需要提升系统权限
  17. if(osvi.dwPlatformId==VER_PLATFORM_WIN32_NT)
  18. {
  19. //EnableShutDownPriv();
  20. }
  21. //判断是否是强制关机,强制关闭系统进程。
  22. dwFlags|=(bForce!=FALSE)?EWX_FORCE:EWX_FORCEIFHUNG;
  23. //调用API
  24. returnExitWindowsEx(dwFlags,0);
  25. }
提升权限的代码:
  1. #pragma region 用来提升系统权限
  2. //这是一个通用的提升权限函数,如果需要提升其他权限
  3. //更改LookupPrivilegeValue的第二个参数SE_SHUTDOWN_NAME,即可
  4. BOOL EnableShutDownPriv()
  5. {
  6. HANDLE hToken=NULL;
  7. TOKEN_PRIVILEGES tkp={0};
  8. //打开当前程序的权限令牌
  9. if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
  10. {
  11. return FALSE;
  12. }
  13. //获得某一特定权限的权限标识LUID,保存在tkp中
  14. if(!LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid))
  15. {
  16. CloseHandle(hToken);
  17. return FALSE;
  18. }
  19. tkp.PrivilegeCount=1;
  20. tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
  21. //调用AdjustTokenPrivileges来提升我们需要的系统权限
  22. if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(TOKEN_PRIVILEGES),NULL,NULL))
  23. {
  24. CloseHandle(hToken);
  25. return FALSE;
  26. }
  27. return TRUE;
  28. }
调用方法:
  1. ReSetWindows(EWX_LOGOFF,false);//注销
  2. ReSetWindows(EWX_REBOOT,true);//重启
  3. ReSetWindows(EWX_SHUTDOWN,true);//关机
具体见自己代码,参见附件。
文章摘自:
http://blog.csdn.net/zy_dreamer/article/details/8948880

附件列表

最新文章

  1. PHP $_SERVER详解
  2. 百度定位并获取县区天气-XML+fragment+sqlite
  3. Cocos2dx开发游戏移植到Android平台
  4. 使用OpenGL ES绘制3D图形
  5. javaweb-dbcp2
  6. cmd下运行PowerShell命令
  7. 在VS2012中GridView的一个坑
  8. Linux 命令 - su: 以其他用户和组 ID 的身份来运行 shell
  9. eval(phpcode) 字符当代码执行
  10. 在at91sam9260处理器上调试linux2.6.33.7的过程
  11. Redis 介绍与使用
  12. AES SHA-1 SM3 MD5
  13. tar+pigz+ssh实现大数据压缩传输
  14. input光标高度问题
  15. 【正则表达式】--python(表示字符)
  16. mysql(3)—— 内连接、外连接的区别
  17. A1066. Root of AVL Tree
  18. python ddt 传多个参数值示例
  19. rsa 加密 pkcs#1格式秘钥的格式化
  20. windows 允许空密码登陆

热门文章

  1. app xml报错
  2. easyUI combobox 控件 使用
  3. Android中Context的理解及使用(二)——Application的用途和生命周期
  4. 用RMAN备份EBS数据库的脚本
  5. Open xml 操作Excel 透视表(Pivot table)-- 实现Excel多语言报表
  6. java基础 swing编程实战
  7. 高程(4):执行环境、作用域、上下文执行过程、垃圾收集、try...catch...
  8. 《C程序设计语言》- 字符输入和输出
  9. Ajax深入解析
  10. Java中的24种设计模式与7大原则