windows C++實現注銷、重啟、關機 logoff reboot shutdown


實現這一功能很簡單,主要需要調用一個系統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

 

 





附件列表

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM