はじめに
GMOコネクトの青山です。bat ファイルを作って実行したら、コマンドプロンプトが一瞬表示されてすぐ消える——そんな経験はありませんか 😵 ログも残らず途方に暮れたのですが、原因は実装ではなく「C:\ 直下に置いていたこと」でした。
先にまとめ
結論:bat ファイルは C:\Users\username\ 配下に置きましょう。
C:\ 直下に置くと書き込み権限エラーでログが出ず、パス変換バグも重なって原因追跡が詰みます。移動するだけで解決しました。
症状
- ダブルクリックするとコマンドプロンプトが一瞬だけ表示されてすぐ消える
- bat の最初でログファイルを出力するようにしていたが、
run.logが生成されない - エラーメッセージが読めないので原因がわからない
ハマり1: C:\ への書き込み権限がない(UAC)
今回の bat は、起動時にまず自分のディレクトリへログを書き出す処理を入れていました。
bat set "SCRIPT_DIR=%~dp0" set "LOG=%SCRIPT_DIR%run.log" echo [%date% %time%] START >> "%LOG%"
C:\ に置くと %LOG% は C:\run.log になります。ここで詰まります。
C:\ 直下は一般ユーザーに書き込みが許可されていない保護領域です。UAC(ユーザーアカウント制御)の制限で、管理者権限なしに C:\run.log を作ろうとすると以下のエラーが返ります。
Access is denied.
bat はこのエラーで止まらず処理を続けますが、同じ理由でその後の処理も全滅し、最終的にウィンドウが閉じます。
ハマり2: C:\ → C: のパス変換バグ
もう一つ落とし穴がありました。
bat 内で末尾の \ を取り除く処理を書いていました。パスを環境変数で別プロセスに渡す際に末尾スラッシュが邪魔になるためです。
bat set "SCRIPT_DIR=%~dp0" :: 末尾の \ を除去 if "%SCRIPT_DIR:~-1%"=="\" set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"
通常のフォルダなら %~dp0 は C:\Users\username\tools\ → 除去後は C:\Users\username\tools になり、これは正しく動きます。
C:\ に置いた場合は %~dp0 が C:\ → 除去後は C: になります。
C:\ と C: は Windows では別物です。
| 表記 | 意味 |
|---|---|
C:\ |
C ドライブのルート(絶対パス) |
C: |
C ドライブのカレントディレクトリ(相対パス扱い) |
C: をベースにパスを組み立てると、実行時のカレントディレクトリ次第で意図しない場所を参照します。今回は環境変数でこの値を別プロセスへ渡していたため、受け取り側のパス組み立てもおかしくなっていました。
解決策
ユーザーディレクトリ配下に移すだけです。
Before: C:\connect-jump.bat After: C:\Users\username\tools\connect-jump.bat
移動後はダブルクリックで正常に起動し、run.log も生成されるようになりました。
「管理者として実行」でも動きますが、毎回右クリックが必要になる上、根本の問題は残るのでおすすめしません。
まとめ
bat が動かないとき、まず疑うのはコードよりも「置き場所」かもしれません。
C:\ 直下は罠が多いです。ユーザーディレクトリに移す、それだけです。
GMOコネクトでは一緒に働く仲間を募集しています。
https://www.gmo-connect.jp/recruit/