コマンドプロンプトからWindowsUpdateを適用して再起動するには

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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です