コマンド実行時のエラーメッセージによって条件分岐してダイアログを表示するバッチ

コマンドプロンプトでコマンド実行エラーが出た場合にエラーメッセージが表示されますが、それによって条件分岐してダイアログメッセージを表示する方法です。
※2018/08/14 加筆修正しました。


目次

  1. エラーメッセージの内容で分岐する例
  2. エラーメッセージをログに書き出す
  3. ログの1行目を取得して条件分岐する

1. エラーメッセージの内容で分岐する例

コマンドが正常に実行された場合は「%ERRORLEVEL%」が0になるのでそれによって分岐できます。
しかしエラーの場合、エラーの種類が異なっても「%ERRORLEVEL%」の数値は同じであることがあり、エラーメッセージの内容による分岐を検討しました。

まずは例を表示します。下に説明があります。

@echo off

rem エラー対象コマンド (例として copy を使用)
copy "C:test1.txt" "C:test2.txt" > %TEMP%copylog.txt 2>&1

rem copylog.txt の1行目を取得
set /p FirstLine=<%TEMP%copylog.txt

if %ERRORLEVEL% equ 0 (
    echo MsgBox "%Firstline: =%", vbInformation, "コピー結果" > %TEMP%tmpMsgbox.vbs
) else if not "%FirstLine:ファイルが見つかりません=%" == "%FirstLine%" (
    echo MsgBox "%Firstline: =% (エラー: %ERRORLEVEL%)", vbExclamation, "コピーエラー" > %TEMP%tmpMsgbox.vbs
) else if not "%FirstLine:同じファイルにコピー=%" == "%FirstLine%" (
    echo MsgBox "%Firstline: =% (エラー: %ERRORLEVEL%)", vbExclamation, "コピーエラー" > %TEMP%tmpMsgbox.vbs
) else (
    echo MsgBox "%Firstline: =% (エラー: %ERRORLEVEL%)", vbCritical, "他のエラー" > %TEMP%tmpMsgbox.vbs
)

%TEMP%tmpMsgbox.vbs
del %TEMP%tmpMsgbox.vbs
del %TEMP%copylog.txt

今回は例として copy コマンドで作成しています。もしコピーが失敗したときには、エラーメッセージとともにエラーレベルの数字を表示するようになっています。


2. エラーメッセージをログに書き出す

copy "C:test1.txt" "C:test2.txt" > %TEMP%copylog.txt 2>&1

コピーを行うと同時に、その結果をTEMPフォルダの “copylog.txt” に出力しています。
コマンドの実行結果は「標準出力」と「標準エラー出力」に分けられていて、「>」を使ってファイルに書き出すことができます。

標準出力は正常に実行されたときの結果で、以下のようにして書き出します。

コマンド 1> Result.txt

「1」が標準出力を表しています。それを「>」で「Result.txt」に書き出すという手順です。
この「1」は省略することができるので、次のように書いても良いです。

コマンド > Result.txt

これに対し、エラー出力は以下のようにして書き出します。

コマンド 2> Error.txt

「2」が標準エラー出力を表しています。この「2」は省略できません。

例示したバッチでは、まず標準出力を “copylog.txt” に書き出し、それからエラー出力「2」を「>」で標準出力「&1」に書き出しています。
この「2>&1」という記述はエラーを取得したいときに良く出てきます。

必要なのはエラー出力だけなので「2>%TEMP%copylog.txt」で書き出せば良さそうなのですが、「copy」コマンドではそれが上手くいきませんでした。そのため「2>&1」を使っています。


3. ログの1行目を取得して条件分岐する

set /p FirstLine=<%TEMP%copylog.txt

「FirstLine」という変数に、”copylog.txt” の1行目を格納します。標準出力やエラー出力は1行目に記録されていますので、これを文字列として取得しています。
このとき「set」コマンドに「/p」オプションを付けておかないと、上手く取得できません。

if %ERRORLEVEL% equ 0 (

ここはコピーが正常にできた場合です。これは良いでしょう。

) else if not "%FirstLine:ファイルが見つかりません=%" == "%FirstLine%" (

これは、変数 FirstLine に「ファイルが見つかりません」という文字列が含まれている場合の分岐です。
コピー元のファイルがない場合のエラー出力は「指定されたファイルが見つかりません。」という文字列になりますので、その場合の分岐です。

) else if not "%FirstLine:同じファイルにコピー=%" == "%FirstLine%" (

この部分はコピー前後のファイルを同一のもので指定してしまったときに「ファイルを同じファイルにコピーすることはできません。」 というエラーになった場合の分岐です。

注目ポイントとしては、上記2つのエラーは両方とも「%ERRORLEVEL%」の数値が「1」であることです。「%ERRORLEVEL%」ではこれを区別して分岐できません。

分岐後の処理はいろいろだと思いますが、今回はメッセージを表示してみました。
「%Firstline: =%」とすることで空白を取り除いて表示しています。なぜか出力メッセージの前後には空白がかなり入っていましたので。
エラーの場合は「%ERRORLEVEL%」の数値も表示されるようにしました。

条件ごとに異なるメッセージボックス内容を一旦VBSに書き出してから実行し、その後削除しています。
copylog.txt も残すほどの情報とは思えないので削除しています。

Leave a comment

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

nine + 1 =