Win32 API ウィンドウズをシャットダウンする
ウィンドウズをシャットダウンやログオフ、再起動するためには、ExitWindowsEx関数を用いる。ExitWindowsEx関数は以下のように定義されている。
BOOL ExitWindowsEx( UINT uFlags, // シャットダウン操作 DWORD dwReserved // 予約済み );
ExitWindowsExで、パワーオフ、再起動、シャットダウンする際には、SE_SHUTDOWN_NAME特権を有効にしておく必要がある。特権を有効にするためには、AdjustTokenPrivileges関数を用いる。
uFlagsの意味は、以下のとおり
値 | 意味 | SE_SHUTDOWN_NAME特権を有効にする必要性 |
EWX_LOGOFF | 現在のユーザーをログオフさせる。 | なし |
EWX_POWEROFF | システムをシャットダウンし、電源を切る。 | あり |
EWX_REBOOT | システムをシャットダウン後、再起動する | あり |
EWX_SHUTDOWN | システムをシャットダウンする。すべてのバッファをディスクへフラッシュし、すべてのプロセスを停止する | あり |
uFlagsで、以下の値をビットの論理和で追加することも可能。
値 | 意味 |
EWX_FORCE | プロセスを強制的に終了させる |
EWX_FORCEIFHUNG | WM_QUERYENDSESSIONまたはWM_ENDSESSIONメッセージに応答しない場合、それらのプロセスを終了させる |
ウィンドウズを強制的にシャットダウンする
#include <windows.h> #include <stdio.h> BOOL EnablePrivileges(LPTSTR lpPrivilegeName, BOOL bEnable) { HANDLE hToken; LUID luid; TOKEN_PRIVILEGES tokenPrivileges; BOOL bRet; //1.OpenProcessToken関数で、プロセストークンを取得する bRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); if (!bRet) { return FALSE; } //2.LookupPrivilegeValue関数で、特権に対応するLUID(ローカル一意識別子)を取得する bRet = LookupPrivilegeValue(NULL, lpPrivilegeName, &luid); if (bRet) { //3.TOKEN_PRIVILEGES型のオブジェクトに、LUID(ローカル一意識別子)と特権の属性(有効にするか無効にするか)を指定する tokenPrivileges.PrivilegeCount = 1; tokenPrivileges.Privileges[0].Luid = luid; tokenPrivileges.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0; //4.AdjustTokenPrivileges関数で、特権を有効にする AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, 0, 0); bRet = GetLastError() == ERROR_SUCCESS; } CloseHandle(hToken); return bRet; } int main() { //SE_SHUTDOWN_NAME(シャットダウン特権) を有効にする if ( !EnablePrivileges(SE_SHUTDOWN_NAME, TRUE) ) { puts("EnablePrivileges failed"); return 1; } if ( !ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0) ) { puts("ExitWindowsEx failed"); return 1; } puts("ExitWindowsEx succeeded !"); return 0; }
参考
http://msdn.microsoft.com/ja-jp/library/cc429713.aspx
http://d.hatena.ne.jp/s-kita/20110409/1302337508