一般的にWindowsをシャットダウン、リブート、ログオフするにはExitWindowsExを使用します。
ExitWindowsEx()の第一引数に種類を指定することで、シャットダウン、リブート、ログオフができます。
Windows95,98の場合は単純にこの関数を呼び出すだけで目的の動作をすることができます。
WindowsNT,Windows2000などNT系のOSではこの関数を呼び出すだけでは、ログオフはできますが、シャットダウン、リブートはうまくいきません。
その理由はヘルプを見れば書いてあります。
「呼び出し側のプロセスが、SE_SHUTDOWN_NAME 特権を持っていなければなりません。」さて、またわかりにくいですね。
どうすれば、この特権をもつことができるのでしょうか。
そこで、「参照」の欄をみると、AdjustTokenPrivileges,HandlerRoutine,SetConsoleCtrlHandlerなどの関数が書いてあります。この最初のAdjustTokenPrivilegesが今回は関係があります。
指定したアクセストークン内のSE_SHUTDOWN_NAME特権を有効しろということです。
よって以下のようになります。ここではエラー処理その他は行っていません。適宜追加してください。
また、Windows98などでは特権関係の関数は呼び出すことはできますが、エラーになりますので、バージョンなどを見分けて呼び分けましょう。
----- #include <windows.h> void ShutdownWindows() { HANDLE hToken = NULL; TOKEN_PRIVILEGES Tp; // Initialize struct ZeroMemory(&Tp, sizeof(Tp)); // Open current prosess's token. OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken); // Lookup current privilege state. Tp.PrivilegeCount = 1; LookupPrivilegeValue("", SE_SHUTDOWN_NAME, &Tp.Privileges[0].Luid); // change privilege state. Tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &Tp, 0, NULL, NULL); // shutdown ExitWindowsEx(EWX_SHUTDOWN, 0); // Resume current privilege state. Tp.Privileges[0].Attributes = 0; AdjustTokenPrivileges(hToken, FALSE, &Tp, 0, NULL, NULL); // close opened token CloseHandle(hToken); } ----- また、この他にもWindowsNTでしか使用できませんが、InitiateSystemShutdownというAPIもあります。 これは、シャットダウンをユーザに知らせるメッセージを出すこと、シャットダウンの中断、シャットダウン までの時間の指定したりすることができます。 上記コードのExitWindowExを呼び出しているところでこのAPIを呼び出せばOKです。
---
上のプログラムを使用したシャットダウンプログラムです。
(ご利用者が本ソフトウェアを使用した結果において、当方は一切の責任を負いません。)
(また、シャットダウンはアクセス中のファイルを正しく閉じずにWindowsを終了してしまう場合もあるため、システムに重大な損害を与える場合があります。ご注意ください)
shutdown.exe + ソース (ExitWindowEx版)
shutdown.exe + ソース ( InitiateSystemShutdown版)
---
更新履歴