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_FORCEIFHUNGWM_QUERYENDSESSIONまたはWM_ENDSESSIONメッセージに応答しない場合、それらのプロセスを終了させる


  • ExitWindowsEx関数の使用例

  • ウィンドウズを強制的にシャットダウンする

    #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