batでプロセス監視をするなら、基本は tasklist /FI "IMAGENAME eq app.exe" で対象プロセスの存在を確認し、停止していたらログ出力・通知・自動再起動へ進める形です。専用監視ツールがなくても、簡易的な異常終了検知ならバッチファイルだけで実装できます。
この記事では、まず tasklist による生存確認、監視ループ、複数プロセス監視、start /wait の終了コード記録、停止時の自動再起動まで、実務で使いやすい順に整理します。
tasklist /FI "IMAGENAME eq myapp.exe"、継続監視は timeout と goto のループ、異常時はログ→通知→再起動の順で段階的に対応します。プロセス監視でよく使う書き方早見表
| 目的 | 書き方 | 使いどころ |
|---|---|---|
| プロセス存在確認 | tasklist /FI "IMAGENAME eq app.exe" |
最も基本の生存確認 |
| 停止判定 | findstr /i "app.exe" >nul |
ERRORLEVEL で分岐 |
| 定期監視 | timeout /t 30 + goto LOOP |
30秒ごとなどに繰り返す |
| 複数プロセス監視 | for %%P in (a.exe b.exe) |
対象をまとめて確認 |
| 終了コードを記録 | start /wait "" "app.exe" |
起動したアプリの終了結果を見る |
| CPU・メモリ監視 | typeperf / PowerShell |
存在確認だけでは足りない場合 |
| 異常時に再起動 | start "" "app.exe" |
停止検知後に自動復旧 |
| タスク化 | schtasks /create ... |
ログオンしていない環境で実行 |
@echo off
setlocal
set "TARGET=myapp.exe"
set "APP_PATH=C:\apps\myapp.exe"
tasklist /FI "IMAGENAME eq %TARGET%" 2>nul | findstr /i "%TARGET%" >nul
if errorlevel 1 (
echo %TARGET% が停止しています。再起動します。
start "" "%APP_PATH%"
exit /b 1
)
echo %TARGET% は動作中です。
exit /b 0
目的別ショートカット
| やりたいこと | 読む場所 | 主なコマンド |
|---|---|---|
| まず書き方だけ知りたい | 書き方早見表 | tasklist /FI |
| 監視方法を比較したい | 方法比較 | tasklist / wmic |
| プロセス停止をログに残したい | 基本チェック | findstr / ログ出力 |
| 常時監視したい | 監視ループ | timeout / goto |
| 複数プロセスをまとめたい | 複数プロセス監視 | for |
| 異常終了後に自動復旧したい | 段階的対応 | ログ / 通知 / 自動再起動 |
| 終了コードを見たい | 終了コード記録 | start /wait |
プロセス監視の方法比較
| 方法 | コマンド | 生存確認 | メモリ/CPU監視 | 終了コード取得 |
|---|---|---|---|---|
| tasklist + findstr | tasklist | findstr /i “app.exe” | ○ | ✕ | ✕ |
| wmic process | wmic process where Name=”app.exe” | ○ | ○(WorkingSetSize) | ✕ |
| start /wait | start /wait “” app.exe | —(起動後に待機) | ✕ | ○(%ERRORLEVEL%) |
| PowerShell | Get-Process -Name app -EA SilentlyContinue | ○ | ○(CPU/RAM詳細) | ✕ |
tasklist | findstr は高速でシンプルですが、プロセス名の部分一致で誤検出するリスクがあります。wmic process where "Name='app.exe'" は完全一致で検索できるため確実です。メモリ使用量なども取得したい場合は wmic か PowerShell を使います。基本:tasklist でプロセス生存確認してログに記録する
@echo off
setlocal
set TARGET=myapp.exe
set LOGFILE=C:\logs\proc_monitor.log
if not exist "C:\logs" mkdir "C:\logs"
REM タイムスタンプ整形
set T=%TIME: =0%
set TS=%DATE% %T:~0,8%
REM /FI でフィルタリング: IMAGENAME が一致するプロセスのみ
tasklist /FI "IMAGENAME eq %TARGET%" 2>nul | findstr /i "%TARGET%" >nul
if %ERRORLEVEL% equ 0 (
echo [%TS%] [OK] %TARGET% 動作中 >> "%LOGFILE%"
) else (
echo [%TS%] [NG] %TARGET% が停止しています! >> "%LOGFILE%"
)
endlocal
tasklist | findstr "app.exe" の代わりにtasklist /FI "IMAGENAME eq app.exe" を使うと完全一致(IMAGENAME が app.exe のプロセスのみ)でフィルタリングできます。findstr "app" では “myapp.exe”・”app_helper.exe” など別プロセスも誤マッチするリスクがあります。tasklist コマンドの詳細な使い方はプロセスの終了を待つ全方法まとめも参照してください。監視ループ:定間隔でプロセスを継続チェックする
バッチファイルを常駐させてプロセスを定期的に監視します。timeout で指定秒数待機してから再チェックするループ構造が基本です。
@echo off
setlocal enabledelayedexpansion
set TARGET=myapp.exe
set LOGFILE=C:\logs\proc_monitor.log
set INTERVAL=30
if not exist "C:\logs" mkdir "C:\logs"
call :log "===== 監視開始 対象: %TARGET% ====="
:MONITOR_LOOP
tasklist /FI "IMAGENAME eq %TARGET%" 2>nul | findstr /i "%TARGET%" >nul
if %ERRORLEVEL% equ 0 (
call :log "[OK] %TARGET% 動作中"
) else (
call :log "[NG] %TARGET% 停止検知!"
)
timeout /t %INTERVAL% /nobreak >nul
goto MONITOR_LOOP
:log
set T=%TIME: =0%
echo [%DATE% %T:~0,8%] %~1 >> "%LOGFILE%"
echo [%DATE% %T:~0,8%] %~1
goto :eof
このバッチを実行するとウィンドウが常駐します。バックグラウンド実行したい場合はタスクスケジューラで「ユーザーがログオンしているかどうかにかかわらず実行する」に設定するか、
start /min "" monitor.bat で最小化して起動してください。Ctrl+C で監視ループを停止できます。複数プロセスを1本のバッチで同時監視する
監視対象のプロセス名をリスト化し、for ループで順番にチェックします。停止しているプロセスをカウントして、全プロセスの状態を1回の実行でまとめて記録できます。
@echo off
setlocal enabledelayedexpansion
set LOGFILE=C:\logs\multi_proc.log
set INTERVAL=60
if not exist "C:\logs" mkdir "C:\logs"
REM 監視対象プロセスをスペース区切りで列挙
set TARGETS=svchost.exe notepad.exe myapp.exe
:MULTI_LOOP
set T=%TIME: =0%
set TS=%DATE% %T:~0,8%
set NG_COUNT=0
echo ===== チェック: %TS% ===== >> "%LOGFILE%"
for %%P in (%TARGETS%) do (
tasklist /FI "IMAGENAME eq %%P" 2>nul | findstr /i "%%P" >nul
if !ERRORLEVEL! equ 0 (
echo [OK] %%P >> "%LOGFILE%"
) else (
echo [NG] %%P 停止! >> "%LOGFILE%"
set /a NG_COUNT+=1
)
)
if %NG_COUNT% gtr 0 (
echo 異常プロセス数: %NG_COUNT% 件 >> "%LOGFILE%"
)
echo. >> "%LOGFILE%"
timeout /t %INTERVAL% /nobreak >nul
goto MULTI_LOOP
wmic でメモリ使用量も含めて監視する
プロセスが「存在するが異常に多くのメモリを消費している」状態もwmicで検知できます。メモリリークや高負荷による異常を捉えるのに有効です。
@echo off
setlocal enabledelayedexpansion
set TARGET=myapp.exe
set LOGFILE=C:\logs\mem_monitor.log
REM メモリ上限(バイト): 500 MB = 524288000
set MEM_LIMIT=524288000
if not exist "C:\logs" mkdir "C:\logs"
:MEM_LOOP
set T=%TIME: =0%
set TS=%DATE% %T:~0,8%
REM プロセスの存在確認
tasklist /FI "IMAGENAME eq %TARGET%" 2>nul | findstr /i "%TARGET%" >nul
if %ERRORLEVEL% neq 0 (
echo [%TS%] [NG] %TARGET% 停止! >> "%LOGFILE%"
goto MEM_WAIT
)
REM WorkingSetSize(バイト)を取得
set MEM=0
for /f "skip=1 tokens=2 delims==" %%M in (
'wmic process where "Name='%TARGET%'" get WorkingSetSize /value'
) do (
if not "%%M"=="" set MEM=%%M
)
set /a MEM_MB=%MEM% / 1048576
if %MEM% gtr %MEM_LIMIT% (
echo [%TS%] [WARN] %TARGET% メモリ使用量超過: !MEM_MB! MB >> "%LOGFILE%"
) else (
echo [%TS%] [OK] %TARGET% メモリ: !MEM_MB! MB >> "%LOGFILE%"
)
:MEM_WAIT
timeout /t 60 /nobreak >nul
goto MEM_LOOP
WorkingSetSize はプロセスが現在使用している物理メモリ(RAM)をバイト単位で返します。タスクマネージャーの「メモリ(プライベート ワーキング セット)」に相当します。1 MB = 1,048,576 バイトで、set /a MEM_MB=MEM / 1048576 で MB 換算できます。ただし set /a は 2 GB 上限があるため、大量メモリを使うプロセスには PowerShell を使ってください。start /wait で終了コードを記録する
プロセスをバッチから起動して終了コードを記録することで、「正常終了(0)」か「異常終了(1以上)」かを後から確認できます。定期実行バッチがエラーで落ちた理由の追跡に有効です。
@echo off
setlocal
set APP=C:\apps\myapp.exe
set LOGFILE=C:\logs\exitcode.log
if not exist "C:\logs" mkdir "C:\logs"
:RUN_LOOP
set T=%TIME: =0%
echo [%DATE% %T:~0,8%] %APP% 起動 >> "%LOGFILE%"
REM start /wait でプロセス終了まで待機
start /wait "" "%APP%"
set EXIT_CODE=%ERRORLEVEL%
set T=%TIME: =0%
if %EXIT_CODE% equ 0 (
echo [%DATE% %T:~0,8%] [OK] 正常終了 EXITCODE=%EXIT_CODE% >> "%LOGFILE%"
) else (
echo [%DATE% %T:~0,8%] [NG] 異常終了 EXITCODE=%EXIT_CODE% >> "%LOGFILE%"
REM 異常終了時は10秒待って再起動
timeout /t 10 /nobreak >nul
goto RUN_LOOP
)
echo 処理完了
endlocal
start /wait でバッチから外部 exe を起動した場合、終了後の %ERRORLEVEL% に終了コードが格納されます。ただし bat ファイルを start /wait "" script.bat で呼び出した場合、bat の終了コードは親バッチの ERRORLEVEL に反映されません(0 が返る)。bat の終了コードを伝播させるには call を使うか、ファイルや環境変数を介して結果を受け渡してください。段階的対応:ログ→ポップアップ通知→自動再起動
異常検知後の対応を段階的に実装します。「まずログに記録 → 画面通知 → 自動再起動 → 再起動が続く場合は監視停止」のフローが実運用で使いやすいパターンです。
@echo off
setlocal enabledelayedexpansion
set TARGET=myapp.exe
set APP_PATH=C:\apps\myapp.exe
set LOGFILE=C:\logs\watchdog.log
set INTERVAL=30
set MAX_RESTART=3
set RESTART_COUNT=0
if not exist "C:\logs" mkdir "C:\logs"
call :log "===== ウォッチドッグ開始 ====="
:WATCHDOG
tasklist /FI "IMAGENAME eq %TARGET%" 2>nul | findstr /i "%TARGET%" >nul
if %ERRORLEVEL% equ 0 (
call :log "[OK] %TARGET% 動作中"
set RESTART_COUNT=0
goto WATCHDOG_WAIT
)
REM --- 異常検知 ---
set /a RESTART_COUNT+=1
call :log "[NG] %TARGET% 停止検知 (再起動: !RESTART_COUNT!/%MAX_RESTART%)"
if !RESTART_COUNT! gtr %MAX_RESTART% (
call :log "[ABORT] 再起動上限到達。監視を停止します。"
msg * "%TARGET% の再起動が上限に達しました。手動確認してください。"
exit /b 1
)
REM ポップアップ通知(ログオン中ユーザーへ)
msg * "[監視] %TARGET% が停止しました。自動再起動します。"
REM 自動再起動
start "" "%APP_PATH%"
call :log "[INFO] %TARGET% を再起動しました"
:WATCHDOG_WAIT
timeout /t %INTERVAL% /nobreak >nul
goto WATCHDOG
:log
set T=%TIME: =0%
echo [%DATE% %T:~0,8%] %~1 >> "%LOGFILE%"
echo [%DATE% %T:~0,8%] %~1
goto :eof
msg * はコンソールセッションにメッセージウィンドウをポップアップ表示します。Windows 10/11 の Home エディションでは動作しない場合があります(Pro/Enterprise 向け機能)。Home エディション環境では代わりに powershell -Command "[System.Windows.Forms.MessageBox]::Show('メッセージ')" または通知ファイルをデスクトップに作成するなどの方法で代替できます。自動再起動の詳細なパターンは一定時間ごとに指定アプリを自動で再起動するスクリプトも参照してください。プロセスの終了を「待つ」パターンはプロセスの終了を待つ全方法まとめ、ネットワーク接続の監視・再接続はネットワーク接続を監視して異常検知・再接続する方法、ログへの時刻記録は実行時刻・経過時間をログに記録する完全ガイドを参照してください。
あわせて確認したい関連記事
- バッチファイル(bat)の目的別記事一覧
- exit /bの使い方|ERRORLEVEL・終了コードを返す方法
- typeperfでCPU・メモリ使用率をログ記録する方法
- schtasksコマンドでタスクスケジューラを制御する方法
- shutdownコマンドの使い方|再起動・予約・スリープ
よくある質問
tasklist /FI "IMAGENAME eq app.exe" を実行し、findstr の ERRORLEVEL で判定します。部分一致を避けるため、まず /FI で絞り込むのがおすすめです。start "" "C:\apps\app.exe" を実行します。再起動回数に上限を設け、連続失敗時はログ出力して停止する設計にすると安全です。:LOOP ラベル、tasklist、timeout /t 30 /nobreak、goto LOOP を組み合わせます。短すぎる間隔はPC負荷やログ肥大の原因になります。Responding、CPU・メモリ使用率の監視を組み合わせてください。for %%P in (a.exe b.exe c.exe) do (...) で対象名を回し、プロセスごとに tasklist /FI を実行します。NG件数を集計して最後に通知すると運用しやすくなります。start /wait "" "app.exe" のあとに%ERRORLEVEL% をログへ書きます。すでに起動済みのプロセスをtasklistで監視するだけでは終了コードは取得できません。typeperf、PowerShellの Get-Process、またはパフォーマンスカウンターを使う方法へ切り替えてください。まとめ
- 存在確認:
tasklist /FI "IMAGENAME eq app.exe"で完全一致チェック - 監視ループ:
:LOOP → tasklist → timeout → goto LOOPの構造で継続監視 - 複数プロセス:
for %%P in (a.exe b.exe)で一括チェック・NG件数を集計 - メモリ監視:
wmic process where Name=... get WorkingSetSizeで使用量を閾値チェック - 終了コード記録:
start /wait "" app.exe後に%ERRORLEVEL%を記録 - 段階的対応: ログ記録 → msg 通知 → 自動再起動 → 上限到達で監視停止
関連記事: プロセスの終了を待つ全方法まとめ / 指定アプリを自動再起動するスクリプト / バッチファイルでログを出力する完全ガイド

