犬でもわかるバッチファイルの作り方〜再起動後も処理を続ける方法!

Windows
inuwaka-batch-05-eyecatch

再起動を挟む処理をバッチで行う際、どういう風にすればいいのか困ってしまう事ありませんか?

再起動を行うタイミングごとに個別のバッチを作るのも一つの手ですが、あまりにバッチが増えると管理が煩雑になってしまって困りものです。

あーあ・・・一つのバッチで再起動後もそのまま処理をしてくれればいいのに。

このレジストリが勝利のカギだ!

という訳で今回のテーマはバッチの処理を再起動後も続けるためのコマンドをご紹介します。

この処理を実現させるには、以下のレジストリのいずれかを使用することで実現することが可能となります。

  • HKLM\Software\Microsoft\Windows\CurrentVersion\Run
  • HKCU\Software\Microsoft\Windows\CurrentVersion\Run
  • HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce
  • HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce
  • HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnceEx
  • HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnceEx

これらのレジストリはそれぞれ何が違うのかというと、関連付けられるユーザーと処理の内容が違います。

HKLMとHKCU

まずは使用するレジストリはHKLM(HKEY_LOCAL_MACHINE)で始まるパスと、HKCU(HKEY_CURRENT_USER)で始まるものに分かれます。

HKLM

HKLMではじまるものは端末に対しての設定となります。
そのため、全てのユーザーのログインをトリガーとして起動します。
基本的にはHKLMのレジストリを使用した方が動作が安定します。

HKCU

HKCUではじまるものは特定のユーザーがログインした場合のみに適用される設定です。
そのため特定のユーザーのログインをトリガーとして起動します。

RunとRunOnceとRunOnceEx

次にレジストリのパスの最後のRunとRunOnceとRunOnceExについて説明します。

RUN

まずは「Run」。これはユーザーがログインするたびにこのレジストリの値に書かれた処理が行われます。
つまりバッチで使用する場合は、ここにバッチへのパスを入力するのですが、詳しい方法は後述します。

RunOnce

RunOnceはユーザーがログインしたら値が削除されるため、一度だけしか処理が行われません。
また、レジストリの値はバッチに記載されたコマンドが実行された段階で削除されます。

RunOnceEx

RunOnceExもRunOnce同様、ユーザーがログインしたら値が削除されるため、一度だけしか処理が行われません。
ただしRunOnceExではコマンド全体が完了するまでレジストリの値が維持されます。

レジストリの違いのまとめ

ここまでの内容を表にしてまとめてみました。

▼クリックで拡大
まとめ

上記の表を参考に、動かしたいバッチの挙動に合わせて適切なレジストリを使用してください。

実際の使用方法

さて必要なレジストリは分かりました。では実際にはどう使うのでしょうか?

そこで以下のようなサンプルバッチを作成しました。

cd /d %~dp0

if "%1" neq "" goto :%1
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" /v "Reboot" /t REG_SZ /d "%~0 1" /f

wmic computersystem where name="%computername%" call rename name="Blog-TESTPC"

Shutdown /r /t 0
exit

:1
echo reboot complete !!

pasue

exit

このバッチは端的に言うと、現在の端末名を「Blog-TESTPC」に変更した後、その設定反映のために再起動を実行、再起動後はcmd上に「reboot complete !!」を表示させます。

ここで注目していただきたいのが以下の2つの処理です。

1つ目の処理内容

if "%1" neq "" goto :%1

1つ目の処理はIfがあるので分かりやすいですが、条件文となっています。
その内容は

もし%1が空白ではなかった場合に、後述の%1の処理を行う

という物です。
ここでいう「後述の%1の処理」は

:1
echo reboot complete !!

のことを指します。

では%1自体はどこで設定しているのか?それが次の処理内容になっております。

2つ目の処理内容

reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" /v "Reboot" /t REG_SZ /d "%~0 1" /f

reg addと書いてあるように、この処理を使用してRunonceのレジストリに以下のように追記します。
2つ目

この追加されたレジストリのバッチまでのパスで、ログイン後に起動するバッチの指定を行い、引数の値によって再起動後に行う処理内容を決定します。

上記の処理を細分化すると以下のようになります。

reg add ~

追加するレジストリのパスを指定します。

/v “Reboot”

追加する値の名前を指定します。

/t REG_SZ

追加するデータの種類を指定します。
今回はバッチファイルまでのパスを指定するため、文字列を指定しています。

/d “%~0 1”

追加するデータの内容になります。
%~0はバッチ自身までのパスを指しています。

何故%~0で?と思った方はこの記事上部でご紹介した「犬でもわかるバッチファイルの作り方~カレントディレクトリを意識しよう!」に書いてありますので、ぜひご覧ください。


またパスの後の1が引数となり、再起動後に行う処理の内容を決定します。
そして一つ目の処理内の「%1」がこの引数のことを指しています。

いざ実践!

では実際に動かしてみましょう。

再起動後に処理を継続するバッチを使用するときは、必ず管理者権限で実行しましょう。

実際の起動画面
分かりやすいように紹介したコードの中に一部pauseを追加しています
■再起動前
再起動前
■再起動後
再起動後
このように処理が途切れずに実行できました。

これを応用すれば以下のように、コンピュータ名変更を行い再起動したのち、コンピュータ名が指定の物に変わっていなければ再度コンピュータ名の変更を行うという処理なんてのもできちゃいます。

cd /d %~dp0

set name=Blog-TESTPC

if "%1" neq "" goto :%1
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" /v "Reboot" /t REG_SZ /d "%~0 1" /f

wmic computersystem where name="%computername%" call rename name="%name%"

Shutdown /r /t 0
exit

:1
if /i not "%computername%"=="%name%" (
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" /v "Reboot" /t REG_SZ /d "%~0 1" /f

wmic computersystem where name="%computername%" call rename name="%name%"

Shutdown /r /t 0
exit
) else (
echo reboot complete !!
)

exit

えっ!?同じ処理内容を使って複数回の再起動を?

先ほどレジストリに記載した引数によって再起動後の処理を決定するとお話しました。

つまりその引数の値を変えてあげれば複数回の再起動でもバッチの処理を進めることが可能となっています。

例えば

cd /d %~dp0

if "%1" neq "" goto :%1
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" /v "Reboot" /t REG_SZ /d "%~0 1" /f

wmic computersystem where name="%computername%" call rename name="Blog-TESTPC"

Shutdown /r /t 0
exit

:1
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" /v "Reboot" /t REG_SZ /d "%~0 2" /f
echo reboot complete !!

pause

Shutdown /r /t 0
exit

:2
echo One More!!

pause

exit

とすればコンピュータ名の変更後再起動→「reboot complete !!」と表示されて再起動→「One More!!」が表示されるという処理になります。

これは「:1」の処理でRunOnceのレジストリに書き込む際に引数を2に変えることで、再起動した際は「:2」の処理を行うように指定しているためです。

最後に

いかがだったでしょうか。

まだまだ奥深いバッチの世界。

powershellに押され気味ですがまだまだバッチは現役です!

バッチをマスターしてあなたもベテランSEへの道を歩みましょう!

これまでの「犬でもわかるバッチファイルの作り方」シリーズ