バッチファイルからプログラム(exe)を実行する方法は、大きく分けて3つあります。直接実行、start コマンド、call コマンドです。
この記事では、3つの方法の違いと使い分け、引数の渡し方、終了コードの取得、エラーハンドリングまで、実務で必要な知識を体系的に解説します。
3つの実行方法の比較
まず全体像を把握します。
| 方法 | 待機 | ウィンドウ | ERRORLEVEL取得 | 主な用途 |
|---|---|---|---|---|
| 直接実行 | する | 同じ | 可能 | 基本の実行 |
start |
しない | 新規 | 不可(/waitで可能) | 並列実行・アプリ起動 |
call |
する | 同じ | 可能 | バッチからバッチを呼ぶ |
方法1:直接実行(最も基本)
exeファイルのパスをそのまま記述します。プログラムが終了するまで次の行に進みません(同期実行)。
@echo off echo プログラムを実行します... "C:Program FilesMyAppapp.exe" echo 終了しました(ERRORLEVEL: %ERRORLEVEL%) pause
PATHが通っている場合
環境変数 PATH に含まれるディレクトリのexeは、ファイル名だけで実行できます。
@echo off rem notepad.exe は PATH が通っているのでファイル名だけで起動できる notepad echo メモ帳を閉じました
notepad、calc、mspaint などのWindows標準アプリはフルパス不要です。
バッチファイルと同じフォルダのexeを実行する
%~dp0 を使うと、バッチファイル自身のフォルダを基準にパスを指定できます。
@echo off rem バッチファイルと同じフォルダにある tool.exe を実行 "%~dp0tool.exe"
%~dp0 はバッチファイルのドライブ文字+フォルダパス(末尾 付き)に展開されます。これにより、バッチファイルをどこに置いても正しく動作します。
方法2:start コマンド(非同期実行)
start はプログラムを別ウィンドウで起動し、バッチファイルは終了を待たずに次の行に進みます。
@echo off rem メモ帳を起動して、すぐ次の行へ進む start notepad echo メモ帳を起動しました(閉じるのを待ちません) pause
start コマンドの主要オプション
| オプション | 意味 | 使用例 |
|---|---|---|
/wait |
プログラム終了まで待機する | start /wait app.exe |
/b |
新しいウィンドウを開かずバックグラウンド実行 | start /b app.exe |
/min |
最小化した状態で起動 | start /min app.exe |
/max |
最大化した状態で起動 | start /max app.exe |
/d "パス" |
作業ディレクトリを指定 | start /d "C:work" app.exe |
/low |
低い優先度で起動 | start /low app.exe |
/high |
高い優先度で起動 | start /high app.exe |
【重要】start コマンドのウィンドウタイトルの罠
start の最も多いハマりポイントです。以下のコードは意図どおりに動きません。
rem NG: パスがウィンドウタイトルとして解釈されてしまう start "C:Program FilesMyAppapp.exe"
start は最初のダブルクォーテーションで囲まれた文字列をウィンドウタイトルとして認識します。そのためパスをクォーテーションで囲むと、アプリが起動せず代わりに新しいコマンドプロンプトが開きます。
正しい書き方は、最初に空のタイトル "" を指定することです。
rem OK: 空のタイトルを先に指定する start "" "C:Program FilesMyAppapp.exe"
この罠はパスにスペースが含まれるときに必ず発生します。start コマンドでは常に先頭に "" を付ける習慣にすると安全です。
start /wait で終了コードを取得する
start 単体ではプログラムの終了コードを取得できませんが、/wait を付けると待機してから ERRORLEVEL を取得できます。
@echo off
start "" /wait "C:MyAppsetup.exe"
echo 終了コード: %ERRORLEVEL%
if %ERRORLEVEL% neq 0 (
echo インストールに失敗しました
)
方法3:call コマンド(バッチからバッチを呼ぶ)
call は主にバッチファイルから別のバッチファイルを呼ぶときに使います。
call なしだと呼び出し元に戻らない
バッチファイルから別のバッチファイルを実行する場合、call を付けないと呼び出し元に制御が戻りません。
@echo off rem NG: sub.bat の実行後、この行以降は実行されない sub.bat echo この行は実行されない
@echo off rem OK: call を付ければ sub.bat 終了後にここに戻ってくる call sub.bat echo sub.bat が終了しました(ERRORLEVEL: %ERRORLEVEL%)
exe の場合は call 不要
exeファイルの実行に call は不要です。exeは直接実行しても呼び出し元に戻ります。call が必要なのは .bat / .cmd ファイルを呼ぶときだけです。
@echo off rem exe は call 不要(直接実行で終了を待つ) "C:MyAppapp.exe" echo app.exe が終了しました rem bat は call 必須(call しないと戻ってこない) call "C:Scriptssub.bat" echo sub.bat が終了しました
引数を渡して実行する
exeやバッチに引数を渡す方法です。
直接実行で引数を渡す
@echo off rem exeに引数を渡す "C:MyAppconverter.exe" input.txt output.csv /silent rem 引数にスペースを含む場合はダブルクォーテーションで囲む "C:MyAppconverter.exe" "C:My Documentsinput.txt" "C:output esult.csv"
start コマンドで引数を渡す
start の場合は、タイトル "" → exe → 引数の順に記述します。
@echo off rem start で引数付き実行(タイトル "" を忘れずに) start "" "C:MyAppconverter.exe" input.txt output.csv /silent rem 終了を待って引数付き実行 start "" /wait "C:MyAppsetup.exe" /S /D=C:InstallDir
変数を使って引数を渡す
@echo off set INPUT_FILE=data.txt set OUTPUT_FILE=result.csv "C:MyAppconverter.exe" "%INPUT_FILE%" "%OUTPUT_FILE%" echo 変換完了(ERRORLEVEL: %ERRORLEVEL%)
終了コード(ERRORLEVEL)を取得する
プログラムの実行結果を判定するには、ERRORLEVEL を確認します。通常、0 が正常終了、0 以外がエラーです。
@echo off
"C:MyAppackup.exe" /auto
if %ERRORLEVEL% equ 0 (
echo バックアップ成功
) else (
echo バックアップ失敗(終了コード: %ERRORLEVEL%)
exit /b %ERRORLEVEL%
)
実行方法ごとの ERRORLEVEL 取得可否
| 実行方法 | ERRORLEVEL取得 | 備考 |
|---|---|---|
| 直接実行 | 可能 | 終了を待ってから取得 |
start(/waitなし) |
不可 | プログラム終了を待たないため |
start /wait |
可能 | /wait で終了を待てば取得可能 |
call |
可能 | bat/cmd の戻り値も取得可能 |
注意:ERRORLEVEL は直後に確認する
ERRORLEVEL は直前に実行したコマンドの終了コードです。間にコマンドを挟むと上書きされます。
rem NG: echo で ERRORLEVEL が 0 にリセットされる
"C:MyAppapp.exe"
echo アプリを実行しました
if %ERRORLEVEL% neq 0 echo エラー <-- 常に 0 になる
rem OK: 実行直後に判定する
"C:MyAppapp.exe"
if %ERRORLEVEL% neq 0 (
echo エラーが発生しました(コード: %ERRORLEVEL%)
exit /b %ERRORLEVEL%
)
echo アプリの実行が完了しました
エラーハンドリング付きの実行
exe の存在確認をしてから実行する
@echo off
set EXE_PATH=C:MyAppapp.exe
if not exist "%EXE_PATH%" (
echo エラー: %EXE_PATH% が見つかりません
exit /b 1
)
"%EXE_PATH%"
if %ERRORLEVEL% neq 0 (
echo エラー: 実行に失敗しました(コード: %ERRORLEVEL%)
exit /b %ERRORLEVEL%
)
echo 正常に完了しました
where コマンドで PATH 上の exe を探す
where コマンドを使うと、PATH 環境変数に含まれるディレクトリからexeを検索できます。
@echo off
where python >nul 2>&1
if %ERRORLEVEL% neq 0 (
echo エラー: python が見つかりません
echo PATH に Python のインストールディレクトリを追加してください
exit /b 1
)
echo Python のパス:
where python
python --version
並列実行(複数プログラムの同時起動)
start コマンドを使えば、複数のプログラムを同時に起動できます。
@echo off echo 3つのアプリを同時に起動します... start "" "C:MyAppapp1.exe" start "" "C:MyAppapp2.exe" start "" "C:MyAppapp3.exe" echo 全アプリを起動しました
全プログラムの終了を待つ
start /wait は1つずつ順番に待つので、並列にはなりません。全プログラムを並列実行して全部の終了を待つには、tasklist で監視します。
@echo off echo 並列処理を開始します... start "" "C:MyApp ask1.exe" start "" "C:MyApp ask2.exe" start "" "C:MyApp ask3.exe" :WAIT_LOOP timeout /t 2 /nobreak >nul tasklist /fi "imagename eq task1.exe" 2>nul | find "task1.exe" >nul && goto WAIT_LOOP tasklist /fi "imagename eq task2.exe" 2>nul | find "task2.exe" >nul && goto WAIT_LOOP tasklist /fi "imagename eq task3.exe" 2>nul | find "task3.exe" >nul && goto WAIT_LOOP echo 全タスクが終了しました
パスにスペースが含まれる場合の注意
C:Program Files のようにスペースを含むパスは、ダブルクォーテーションで囲む必要があります。
@echo off rem NG: スペースで区切られてエラーになる C:Program FilesMyAppapp.exe rem OK: パス全体をダブルクォーテーションで囲む "C:Program FilesMyAppapp.exe" rem OK: start の場合はタイトル "" を忘れずに start "" "C:Program FilesMyAppapp.exe"
変数にパスを入れている場合も同様です。
@echo off set APP_PATH=C:Program FilesMyAppapp.exe rem NG: 変数展開後にスペースで分割される %APP_PATH% rem OK: 変数もクォーテーションで囲む "%APP_PATH%"
実践テンプレート
テンプレート1:exe を安全に実行する
@echo off
setlocal
cd /d "%~dp0"
set EXE_PATH=C:MyAppapp.exe
set LOG_FILE=%~dp0exec.log
rem 存在確認
if not exist "%EXE_PATH%" (
echo [%date% %time%] エラー: %EXE_PATH% が見つかりません >> "%LOG_FILE%"
echo エラー: 実行ファイルが見つかりません
exit /b 1
)
rem 実行
echo [%date% %time%] 実行開始: %EXE_PATH% >> "%LOG_FILE%"
"%EXE_PATH%"
set RESULT=%ERRORLEVEL%
rem 結果判定
if %RESULT% equ 0 (
echo [%date% %time%] 正常終了 >> "%LOG_FILE%"
echo 正常に完了しました
) else (
echo [%date% %time%] 異常終了(コード: %RESULT%) >> "%LOG_FILE%"
echo エラーが発生しました(コード: %RESULT%)
)
endlocal
exit /b %RESULT%
テンプレート2:複数アプリの一括起動
@echo off echo === 開発環境を起動します === rem エディタ start "" "C:Program FilesMicrosoft VS CodeCode.exe" rem ブラウザ(URLを引数に渡す) start "" "C:Program FilesGoogleChromeApplicationchrome.exe" "http://localhost:3000" rem ターミナル(最小化で起動) start "" /min cmd /k "cd /d C:Projectsmyapp && npm run dev" echo 全アプリを起動しました timeout /t 3 >nul
まとめ
| やりたいこと | 方法 |
|---|---|
| exeを実行して終了を待つ | "C:pathapp.exe"(直接実行) |
| exeを起動して次の処理に進む | start "" "C:pathapp.exe" |
| バッチから別のバッチを呼ぶ | call sub.bat |
| 非同期起動で終了コードも取得したい | start "" /wait "C:pathapp.exe" |
| 複数exeを同時に起動する | start を複数行書く |
| exe の存在を確認してから実行 | if not exist で事前チェック |
| PATH上のexeを探す | where app.exe |
ポイント:
startではパスをクォートする前に必ず空のタイトル""を先に書くcallが必要なのはbat/cmd ファイルを呼ぶときだけ。exeには不要ERRORLEVELは実行直後に確認する(間にコマンドを挟まない)- スペースを含むパスはダブルクォーテーションで囲む
%~dp0を使えばバッチファイルの場所を基準にexeを指定できる
