实现这一功能很简单,主要需要调用一个系统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

附件列表

windows C++实现注销、重启、关机 logoff reboot shutdown的更多相关文章

  1. C/C++控制Windows关机/注销/重启的正确姿势

    简介 说到代码控制Windows关机/注销/重启的方式,有很多种,最简单的不过就是控制命令行,使用system("pause")函数执行一个shutdown -s -t 0,关机就 ...

  2. linux注销、关机、重启

    一.Logout 注销是登陆的相对操作,登陆系统后,若要离开系统,用户只要直接下达logout命令即可:[root@laolinux root]#logoutRed Hat Linux release ...

  3. linux注销开关机

    注销:exit 重启:reboot shutdown-r 表示延时分钟数   关机:halt shut -h  

  4. linux基本命令-注销、关机、重起

    链接地址:http://blog.163.com/bhao_home/blog/static/6647763120081202047945/ 一.注销,关机,重启 注销系统的logout命令 1,Lo ...

  5. Linux 登录、注销与关机

    Linux 登录.注销与关机 这里主要学习的是命令行环境下的相关操作. 一.登录 Linux 默认的情况下会提供六个终端来让用户登录,切换的方式为使用:[Ctrl + Alt + F1 ~ F6]的组 ...

  6. Windows 8 自带定时关机的4种实现方法

    问题描述:前几天发布了一篇文章[ Windows 7/8 自带定时关机命令 ],文章中的用到的命令我在Windows 7都运行成功,但没有在Windows 8 上进行测试,因为我认为Windows 8 ...

  7. linux杂记(五)正确关机方法(shutdown,reboot,init,halt)

    前言:由于在linux底下,每个程序(或者说是服务)都是在背景下运行的,因此,在你看不到的屏幕背后其实可能有相当多人同时在你的主机上面工作,如果 你直接按下电源开关来关机,则可能导致其他人的数据就此中 ...

  8. Ubuntu重启关机命令使用

    如果你想保持当前用户的登录而且使用root用户执行命令 可以输入:su root,输入密码 可以运行,shutdown 命令 重启命令: 1.reboot 2.shutdown -r now 立刻重启 ...

  9. Linux下关机命令的区别 (halt,poweroff,reboot,shutdown,init)

    1.shutdown shutdown命令安全地将系统关机.    而在系统关机前使用shutdown命令﹐系统管理员会通知所有登录的用户系统将要关闭.并且login指令会被冻结﹐即新的用户不能再登录 ...

随机推荐

  1. 查看Mysql版本号 (最简单的是status )

    一.使用命令行模式进入mysql会看到最开始的提示符;二.命令行中使用status可以看到;三.使用系统函数等等,   查看版本信息 #1使用命令行模式进入mysql会看到最开始的提示符 Your M ...

  2. 利用filter过虑用户请求URI显示对应页面内容

    目的:只是想验证一下filter对URI的过滤 流程讲解:浏览器请求URI,所有请求都走过虑器,在过滤器中处理符合某种请求的URI然后显示对应的页面内容 有2个JSP页面: index.jsp: &l ...

  3. Rest webservice 和SOAP webservice

    SOAP: 简单对象访问协议(Simple Object Access Protocol,SOAP)是一种基于 XML 的协议,可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP) ...

  4. Nginx笔记

    基础篇 关于Nginx Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器.最早由俄罗斯的程序设计师Igor Sysoev所开发,并在一个BSD-like ...

  5. 数据存储_FMDB

    一.简单说明 1.什么是FMDB FMDB是iOS平台的SQLite数据库框架 FMDB以OC的方式封装了SQLite的C语言API 2.FMDB的优点 使用起来更加面向对象,省去了很多麻烦.冗余的C ...

  6. 批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor

    批量解密SQLSERVER数据库中的各种对象的工具dbForge SQL Decryptor2.1.11 之前写过一篇文章,使用redgate公司的SQL PROMPT工具,但是不太方便 SQLPRO ...

  7. MyBatis传入多个参数的问题

    一.单个参数: public List<XXBean> getXXBeanList(String xxCode); <select id="getXXXBeanList&q ...

  8. php-fpm启动,重启,终止操作

    最近安装了mysqli扩展,重启了nginx后,phpinfo()没有显示出mysqli,后来搞不出原因,直接使用了pdo连接数据库.直到今天安装redis后phpinfo()没有显示redis,内心 ...

  9. 在Parallel中使用DbSet.Add()发现的一系列多线程问题和解决过程

    发现问题 需求很简单,大致就是要批量往数据库写数据,于是打算用Parallel并行的方式写入,希望能利用计算机多核特性加快程序执行速度.想的很美好,于是快速撸了类似下面的一串代码: using (va ...

  10. bzoj2928: [Poi1999]飞弹

    惨啊…… 被卡常是一种什么感受&…… 很明显的分治. 我们首先可以找到所有点中的最低点,然后对所有点进行一次极角排序,选取一个点使得他各侧飞弹和地堡一样多,并对两侧继续进行分治. 很容易证明这 ...