2013年5月25日 星期六

[Win32] 關機及重開機(shutdown and restart)

關機和重開機(shutdown and restart)首先要先調高你的程序(process)到可以關機及重開機的權限,
然後在利用這個InitiateSystemShutdown API來達到關機和重開的功能。

我們來介紹一下InitiateSystemShutdown這個API,依照MSDN的描述,

BOOL WINAPI InitiateSystemShutdown(
_In_opt_ LPTSTR lpMachineName,
_In_opt_ LPTSTR lpMessage,
_In_ DWORD dwTimeout,
_In_ BOOL bForceAppsClosed,
_In_ BOOL bRebootAfterShutdown
);

lpMachineName [in, optional]: 如果您想要關閉另一台電腦,在這裡則要輸入那台電腦的網路名稱;反之如果設成NULL,則表示關閉當下這台電腦。
lpMessage [in, optional]: 這裡是用來設定關機對話框的內容描述。
dwTimeout [in]: 搭配第二個參數,用來設定對話框的停留的時間,如果設定成零的話,就不會顯示對話框,然後直接關機。
bForceAppsClosed [in]:如果為TRUE,應用程式不會被存檔,即會強迫馬上關機,所以資料有可能會遺失。
如果為FALSE,系統會顯示一個對話框,來引導使用者去關閉其它已開啟的應用程式。
bRebootAfterShutdown [in]:如果為TRUE為重開的意思,如果為FALSE則是關機。

程式碼如下:
void shutdown()
{
 HANDLE hToken; 
 TOKEN_PRIVILEGES tkp; 
 BOOL fResult; 

 // Get the current process token handle so we can get shutdown privilege.
 if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  printf("OpenProcessToken failed.");

 // Get the LUID for shutdown privilege.
 LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
 tkp.PrivilegeCount = 1; // one privilege to set
 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

 // Get shutdown privilege for this process.
 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);

 if (GetLastError() != ERROR_SUCCESS)
  printf("AdjustTokenPrivileges enable failed.");

 fResult = InitiateSystemShutdown( NULL, NULL, 0, FALSE, FALSE); //最後一個參數,TRUE表示重開機,FASLE表示關機
 if (!fResult)
 {
  printf("InitiateSystemShutdown failed.");
 }

 // Disable shutdown privilege.
 tkp.Privileges[0].Attributes = 0;
 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0);

 if (GetLastError() != ERROR_SUCCESS)
 {
  printf("AdjustTokenPrivileges disable failed.");
 } 
}

沒有留言:

張貼留言