C++ 实现系统注销,重启,关机的方法

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

ExitWindowsEx

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

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

函数原型

[cpp]  view plain  copy
  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。

[cpp]  view plain  copy
  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.     return ExitWindowsEx(dwFlags,0);  
  25. }  
提升权限的代码:

[cpp]  view plain  copy
  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. }  
调用方法:

[cpp]  view plain  copy
  1. ReSetWindows(EWX_LOGOFF,false);//注销  
[cpp]  view plain  copy
  1. ReSetWindows(EWX_REBOOT,true);//重启  
[cpp]  view plain  copy
  1. ReSetWindows(EWX_SHUTDOWN,true);//关机  

大家测试的时候一定要在虚拟机上测试,不然一运行系统熄火了岂不是很郁闷!


方法二:

#include <iostream>
#include <string>
 
using  namespace  std;
 
void  print()
{
      system "CLS"  );
      system "title C++ 关机程序"  ); //设置cmd窗口标题
      system "mode con cols=52 lines=17"  ); //窗口宽度高度
      system "color 8f"  );
      cout <<  " ╔═══════════════════════╗\n"
           <<  " ║               C++ 关机程序                   ║\n"
           <<  " ║  请输入:                                    ║\n"
           <<  " ║      1.实现定时关闭计算机                    ║\n"
           <<  " ║      2.立即关闭计算机                        ║\n"
           <<  " ║      3.注销计算机                            ║\n"
           <<  " ║      4.重新启动计算机                        ║\n"
           <<  " ║      5.取消关机或注销操作(留意右下角提示)    ║\n"
           <<  " ║      0.退出系统(当然直接关闭是一样的)        ║\n"
           <<  " ║  ※制作人:中山大学软件学院钟嘉聪※          ║\n"
           <<  " ║  ※QQ:172367155※                           ║\n"
           <<  " ╚═══════════════════════╝\n" ;
}
int  main()
{
     string c;
     char  cmds[ 25 ] =  "shutdown -s -t 000000000" ;
     print();
     cin >> c;
     while ( c !=  "0"  )
     {
            while ( c ==  "1"  )
            {
                   int  num;
                   cout <<  "Please enter the time: "  << endl;
                   cin >> num;
                   for int  i = 0; i < 9; i++ )
                   {
                        cmds[ 23 - i ] =  static_cast char  >( num % 10 + 48 );
                        num = num / 10;
                   }
                   system ( cmds );
                   break ;
            }
            while ( c ==  "2"  )
            {
                   system "shutdown -p"  );
                   break ;
            }
            while ( c ==  "3"  )
            {
                   system "shutdown -l"  );
                   break ;
            }
            while ( c ==  "4"  )
            {
                   system "shutdown -r -t 0"  );
                   break ;
            }
            while ( c ==  "5"  )
            {
                   system "shutdown -a"  );
                   break ;
            }
            print();
            cin >> c;
     }
     return  0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值