WindowsUpdateを適用して再起動するコマンドは用意されていないが、InitiateShutdown APIを使用すればWindowsUpdateを適用して再起動するアプリケーションを作ることは容易に出来る。サーバーの運用では指定の時間にWindows Updateを適用して再起動する様な処理が必要になる事が多いが、このAPIを使用して自作したコマンドをタスクに登録しておけば良い。
以下がサンプルコード。
#include "stdafx.h" #include <stdlib.h> #include <Windows.h> #include <winreg.h> int wmain() { // 引数文字列の解析 DWORD dwShutdownFlags = 0; bool showHelp = false; LPTSTR comment = NULL; for (int i = 0; i < __argc; i++) { if (0 == _tcsicmp(__targv[i], _T("/r")) || 0 == _tcsicmp(__targv[i], _T("-r"))) { dwShutdownFlags |= SHUTDOWN_RESTART; } if (0 == _tcsicmp(__targv[i], _T("/s")) || 0 == _tcsicmp(__targv[i], _T("-s"))) { dwShutdownFlags |= SHUTDOWN_POWEROFF; } if (0 == _tcsicmp(__targv[i], _T("/n")) || 0 == _tcsicmp(__targv[i], _T("-n"))) { dwShutdownFlags |= SHUTDOWN_NOREBOOT; } if (0 == _tcsicmp(__targv[i], _T("/f")) || 0 == _tcsicmp(__targv[i], _T("-f"))) { dwShutdownFlags |= SHUTDOWN_FORCE_OTHERS; } if (0 == _tcsicmp(__targv[i], _T("/u")) || 0 == _tcsicmp(__targv[i], _T("-u"))) { dwShutdownFlags |= SHUTDOWN_INSTALL_UPDATES; } if (0 == _tcsicmp(__targv[i], _T("/m")) || 0 == _tcsicmp(__targv[i], _T("-m"))) { i++; if (i < __argc) comment = __targv[i]; } if (0 == _tcsicmp(__targv[i], _T("/h")) || 0 == _tcsicmp(__targv[i], _T("-h"))) { showHelp = true; } } if (showHelp) { _tprintf(_T("/r : The computer is shut down and rebooted.\n")); _tprintf(_T("/s : The computer is shut down and powered down.\n")); _tprintf(_T("/n : The computer is shut down but is not powered down or rebooted.\n")); _tprintf(_T("/u : The computer installs any updates before starting the shutdown.\n")); _tprintf(_T("/f : All sessions are forcefully logged off.\n")); } else { HANDLE hToken; TOKEN_PRIVILEGES TokenPri; // プロセストークンを取得 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) == FALSE) { return GetLastError(); } // シャットダウン権限の LUID を取得 if (LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &TokenPri.Privileges[0].Luid) == FALSE) { return GetLastError(); } // シャットダウン権限を与える TokenPri.PrivilegeCount = 1; TokenPri.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &TokenPri, 0, (PTOKEN_PRIVILEGES)NULL, 0); if (GetLastError() != ERROR_SUCCESS) { return GetLastError(); } // Windows Updateを適用して再起動する DWORD errCode = ::InitiateShutdown(NULL, comment, 0, dwShutdownFlags, SHTDN_REASON_MINOR_OTHER); _tprintf(_T("InitiateShutdown Result Code = 0x%08X.\n"), errCode); return errCode; } return 0; }
以下はバイナリ(実行ファイル)のダウンロード
InitiateShutdown_x32
InitiateShutdown_x64