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