LoginSignup
3
6

More than 5 years have passed since last update.

OSのバージョン・ビットに応じてレジストリを更新するバッチ

Last updated at Posted at 2018-01-22

要件

  • とあるアプリケーションのレジストリをバッチで更新したい
    • HKLM\SOFTWARE以下なので、管理者権限ユーザのみ実行可能とする
  • 対象OSは、Windows8.1、10
    • 32bit版と64bit版両方を対象とする
  • アプリケーションがインストールされてない場合は、処理を実行しない
    • 不要なレジストリは登録しない

処理の流れ

  1. 管理者ユーザで、かつ、管理者権限でプロンプトを実行する
    • ローカルユーザの場合、処理中断
    • 管理者ユーザで、かつ通常プロンプトでバッチが実行された場合、管理者権限プロンプトに昇格し、以降の処理を実行する
  2. OSのバージョンをチェックする
    • Win8.1、10のみ、次処理に引き継ぐ
  3. bitをチェックする
    • レジストリが64bitと32bitで格納場所が異なるため、bitに応じて処理対象レジストリパスを判定する
  4. レジストリキーをチェックする
    • 更新対象レジストリキーが存在する事をチェックする
    • アプリケーションの存在有無は、レジストリチェックを持って代用する
  5. レジストリキーを更新する

レジストリ更新バッチ

RegistoryUpdater.bat
@echo off

echo **** レジストリ更新処理: %date% %time%

SETLOCAL enabledelayedexpansion

rem -- 64bit版 レジストリのパス
set REG_64_ROOT=HKLM\SOFTWARE\Wow6432Node\Sample

rem -- 32bit版 レジストリのパス
set REG_32_ROOT=HKLM\SOFTWARE\Sample

rem -- カレントディレクトリを基準とする
cd /d %~dp0

rem ----------------------------------------------
rem --- 管理者実行チェック&昇格処理
:checkMandatoryLevel
rem --- ▼管理者として実行されているか確認 START
for /f "tokens=1 delims=," %%i in ('whoami /groups /FO CSV /NH') do (
    if "%%~i"=="BUILTIN\Administrators" set ADMIN=yes
    if "%%~i"=="Mandatory Label\High Mandatory Level" set ELEVATED=yes
)

if "%ADMIN%" neq "yes" (
    rem -- Administratorsグループでない(ローカルユーザの場合)
    echo 管理者権限を持たない為、処理を中断します。

    rem --- 処理終了
    goto exit1
)
if "%ELEVATED%" neq "yes" (
    rem -- (プロセスが昇格されていない) Admin権限ありユーザが通常実行した場合
    echo このファイルは管理者権限での実行が必要です
    echo 昇格を行いますので、しばらくお待ちください

    goto runas
)
rem --- ▲管理者として実行されているか確認 END

:admins
    rem --- ▼管理者として実行したいコマンド START

    rem --- OSチェック処理
    CALL :checkOS

    rem --- ▲管理者として実行したいコマンド END
    goto exit1

:runas

    if "%1" == "" (
        rem --- 引数なしのため、★管理者として再実行
        @powershell -NoProfile -ExecutionPolicy unrestricted -Command "Start-Process %~f0 REPEATED -Verb runas"
    ) else (
        rem --- 引数ありのため、すでに自身を再実行している。
        rem --- 処理終了
        echo 管理者への昇格に失敗しました。処理を中断します。
    )

goto exit1

rem ----------------------------------------------
rem --- OSチェックサブルーチン
:checkOS

echo OS: 
call ver

rem --- OSのバージョン確認(Win7) → 処理中断
ver | find /i "Version 6.1." > nul
if %ERRORLEVEL% equ 0 goto :checkOS_WIN7
rem --- OSのバージョン確認(Win8.1) → bitチェック
ver | find /i "Version 6.3." > nul
if %ERRORLEVEL% equ 0 goto :checkBit
rem --- OSのバージョン確認(Win10) → bitチェック
ver | find /i "Version 10.0." > nul
if %ERRORLEVEL% equ 0 goto :checkBit
rem --- それ以外の場合、処理終了
goto :exit1

exit /B


rem ----------------------------------------------
rem -- OSチェック結果:Win7
:checkOS_WIN7
echo Windows7は処理対象外のため、終了します。

goto :exit1

exit /B


rem ----------------------------------------------
rem -- bitチェック
:checkBit

echo bit: %PROCESSOR_ARCHITECTURE%

rem --- OSのbit確認(64bit)
if %PROCESSOR_ARCHITECTURE% == AMD64 GOTO :checkBitResult64
rem --- OSのbit確認(32bit)
if %PROCESSOR_ARCHITECTURE% == x86 GOTO :checkBitResult32
rem --- それ以外の場合、処理終了
goto :exit1

exit /B


rem ----------------------------------------------
rem -- bitチェック結果(64bit)
:checkBitResult64

rem -- 64bit版のパスを保持する
set REG_ROOT=%REG_64_ROOT%

rem -- レジストリ確認処理実行
goto :checkpRegistory

exit /B


rem ----------------------------------------------
rem -- bitチェック結果(32bit)
:checkBitResult32

rem -- 32bit版のパスを保持する
set REG_ROOT=%REG_32_ROOT%

rem -- レジストリ確認処理実行
goto :checkpRegistory

exit /B



rem ----------------------------------------------
rem -- レジストリ確認処理
:checkpRegistory

echo レジストリ確認: %REG_ROOT%

reg query %REG_ROOT% /v EnableSample | find /i "EnableSample" > nul
rem -- レジストリが存在するため、レジストリ更新処理実行
if %ERRORLEVEL% equ 0 goto :updatepRegistory
rem --- それ以外の場合、処理終了

echo 更新対象レジストリが存在しないため、処理を中断します。

goto :exit1

exit /B


rem ----------------------------------------------
rem -- レジストリ更新処理
:updatepRegistory

echo レジストリを更新します。

rem -- レジストリ更新処理実行
reg add %REG_ROOT% /v EnableSample /t REG_DWORD /d 1 /f

rem -- 処理終了
goto :exit1

exit /B




rem ----------------------------------------------
rem -- 終了処理
:exit1

    echo **** レジストリ更新処理終了

    exit

参考)
- バッチファイル(*.bat) を管理者として実行するための バッチファイル
- Windows OS のバージョン情報を判定して条件分岐させるバッチファイル【共通編】
- コマンドプロンプトで64bitか32bitを調べる方法: 京都きもの屋IT系ブログ

おまけ

上記バッチには不採用になったが、色々なパターンを想定してたサンプルを作ったので、供養。

アプリケーションのバージョンチェック

EXEやDLLのプロパティ>詳細>ファイルバージョンに記載されている値を取得するバッチコマンド
#どっちかというと、Powershellの結果をバッチ側で取得するサンプル、かな…

ExeVerCheck.bat
set EXE_PATH=C:\Program Files\Microsoft Office\Office14\EXCEL.EXE

echo EXEパス: %EXE_PATH%

FOR /F "usebackq" %%i IN (`Powershell -Command "return (Get-ItemProperty '%EXE_PATH%').VersionInfo.FileVersion"`) DO SET EXE_VER=%%i

echo EXEバージョン: %EXE_VER%

レジストリの更新チェック

該当レジストリキーの項目だけ更新できているかチェック。
他のキーを更新している等、diff結果が該当キー以外にもヒットした場合、リストアする。

RegDiff.bat
rem -- 管理者権限チェック・昇格処理は省略。

rem -- 更新対象レジストリパス
set REG_ROOT=HKLM\SOFTWARE\Sample\

rem -- ★比較用レジストリファイル
set REG_BEFORE=RegBefore.reg
set REG_AFTER=RegAfter.reg

rem -- カレントディレクトリを基準とする
cd /d %~dp0

rem ---------------------------------------------------
rem -- レジストリ確認処理
:checkRegistory

echo レジストリルート: %REG_ROOT%

rem -- レジストリ存在チェック
reg query %REG_ROOT% /v EnableSample | find /i "EnableSample" > nul
rem -- レジストリが存在するため、レジストリ更新処理実行
if %ERRORLEVEL% equ 0 goto :changeRegistory

rem --- それ以外の場合、処理終了
echo レジストリが存在しないため、処理を中断します。

goto :exit1

rem - サブルーチンの終了
exit /B



rem ---------------------------------------------------
rem -- レジストリ更新処理
:changeRegistory

rem -- ★変更前レジストリを保存(上書き許可)
reg export %REG_ROOT% %REG_BEFORE% /y

echo レジストリを更新します。
reg add %REG_ROOT% /v EnableSample /t REG_DWORD /d 1 /f

rem -- ★更新後のレジストリを保存(上書き許可)
reg export %REG_ROOT% %REG_AFTER% /y

rem -- ★レジストリファイルの比較
rem -- fc: Windows標準diffコマンド
rem -- 不一致行の前後の一致行も常に表示される
rem -- /uオプション: unicodeで比較する
fc /U %REG_AFTER% %REG_BEFORE%

rem -- レジストリ比較結果保持
set REG_DIFF=""

rem -- ★実際に相違のある行のみを表示する
rem -- F=0 → ***** に囲まれたファイル1表示の外側
rem -- F=1 → ファイル1表示の先頭行なので表示しない
rem -- F=2 → ファイル1表示の2行目。F=3の処理と合わせるため一時保管しておく
rem -- F=3 → 同3行目以降。最終行かもしれないのですぐに表示出来ないので一時保管する
rem --    ただし、さっき一時保管した行があるはずなのでまずそれを表示する
rem -- ***** %1 と等しい行 → F=1にする
rem -- ***** %2 と等しい行 → 最終行が保管されているが表示せずF=0にする
set F=0
for /f "skip=1 delims=" %%A in ('fc /U %REG_AFTER% %REG_BEFORE%') do (
    if /i "%%A"=="***** %REG_BEFORE%" ( set F=0
    ) else if /i "%%A"=="***** %REG_AFTER%" ( set F=1
    ) else if !F!==1 ( set F=2
    ) else if !F!==2 ( set F=3&set SAVE=%%A&set REG_DIFF=%REG_DIFF%_%%A
    ) else if !F!==3 ( echo.!SAVE!&set SAVE=%%A)
)

rem -- 比較部分の文字列からダブルクォーテーションを除く
set REG_DIFF=%REG_DIFF:"=%

rem -- 正常に更新された場合
if "%REG_DIFF%" == "_EnableSample=dword:00000001" goto :updatedRegistory
rem -- 更新が行われなかった(既に更新済み)の場合
if "%REG_DIFF%" == "" goto :updatedRegistory
echo レジストリが不正に更新された可能性があります。restoreします。
goto :restoreRegistory

exit /B



rem ---------------------------------------------------
rem -- レジストリ更新正常終了
:updatedRegistory

echo レジストリが正常に更新されました。

goto exit1

exit /B



rem ---------------------------------------------------
rem -- レジストリ更新以上終了
:restoreRegistory

echo レジストリの更新に失敗したため、リストアします。

reg import %REG_BEFORE%

goto exit1

exit /B


:exit1

    exit

参考) ファイル比較結果の相違点のみ取得したい (DOSプロンプト活用相談室LOG)

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6