要想編程使Windows關機、重啟或者注銷,可以使用ExWindowsEx這個API函數,該函數只有兩個參數,第一個表示關機動作的標志,也就是你要讓該函數關機呢,還是重啟,還是注銷等。可以使用EWX_SHUTDOWN、EWX_REBOOT、EWX_LOGOFF等標志常量,分別表示關機、重啟、注銷。另外如果加上EWX_FORCE這個標志常量的話,該表明強制執行該操作。Windows在執行以上操作的時候會首先給每個正在運行中的程序發送一個WM_QUERYENDSESSION消息,告訴它們現在我要退出系統了,你們趕快保存東西啊!如果這時候其中有某一個程序對該消息回應了“不”,系統就不會再執行以上操作了。而如果指定了EWX_FORCE標志,系統則不會發送消息去詢問各個程序了,而是直接強制關閉所有程序,退出系統。所以說當指定了EWX_FORCE標志的時候要小心,因為這樣做可能會丟失一些東西。(比如文件可能會沒保存)。第二參數是保留參數,可能直接傳遞0值。另外,當在Win2K以上的操作系統執行關機和重啟操作時,需要調用該程序的進程首先獲得關機特權,不然函數會調用失敗。
#include
//使能關機特權函數
BOOL EnableShutdownPrivilege()
{
HANDLE hProcess = NULL;
HANDLE hToken = NULL;
LUID uID = {0};
TOKEN_PRIVILEGES stToken_Privileges = {0};
hProcess = ::GetCurrentProcess(); //獲取當前應用程序進程句柄
if(!::OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES,&hToken)) //打開當前進程的訪問令牌句柄(OpenProcessToken函數調用失敗返回值為零)
return FALSE;
if(!::LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&uID)) //獲取權限名稱為"SeShutdownPrivilege"的LUID(LookupPrivilegeValue函數調用失敗返回值為零)
return FALSE;
stToken_Privileges.PrivilegeCount = 1; //欲調整的權限個數
stToken_Privileges.Privileges[0].Luid = uID; //權限的LUID
stToken_Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //權限的屬性,SE_PRIVILEGE_ENABLED為使能該權限
if(!::AdjustTokenPrivileges(hToken,FALSE,&stToken_Privileges,sizeof stToken_Privileges,NULL,NULL)) //調整訪問令牌裡的指定權限(AdjustTokenPrivileges函數調用失敗返回值為零)
return FALSE;
if(::GetLastError() != ERROR_SUCCESS) //查看權限是否調整成功
return FALSE;
::CloseHandle(hToken);
return TRUE;
}
//關機函數
BOOL Shutdown(BOOL bForce)
{
EnableShutdownPrivilege(); //使能關機特權函數
if(bForce)
return ::ExitWindowsEx(EWX_SHUTDOWN EWX_FORCE,0); //強制關機
else
return ::ExitWindowsEx(EWX_SHUTDOWN,0);
}
//注銷函數
BOOL Logoff(BOOL bForce)
{
if(bForce)
return ::ExitWindowsEx(EWX_LOGOFF EWX_FORCE,0); //強制注銷
else
return ::ExitWindowsEx(EWX_LOGOFF,0);
}
//重啟函數
BOOL Reboot(BOOL bForce)
{
EnableShutdownPrivilege(); //使能關機特權函數
if(bForce)
return ::ExitWindowsEx(EWX_REBOOT EWX_FORCE,0); //強制重啟
else
return ::ExitWindowsEx(EWX_REBOOT,0);
}
int main()
{
Logoff(FALSE); //注銷
Reboot(FALSE); //重啟
Shutdown(FALSE); //關機
Logoff(TRUE); //注銷
Reboot(TRUE); //重啟
Shutdown(TRUE); //關機
return 0;
}