【bat】バッチファイルでプログラム(exe)を実行する方法

【bat】バッチファイルでプログラム(exe)を実行する方法 bat

バッチファイルからプログラム(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 メモ帳を閉じました

notepadcalcmspaint などの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を指定できる

あわせて読みたい