自作プログラムの起動用batファイルを作成し、プログラム本体とbatファイルを同一フォルダにまとめておくとする。
たとえば以下のような構成の時、各プログラムのフルパス指定等をどのように書けばいいか。
MyPGFolder
├ execMyPG.bat
├ Dependency
│ └ OtherPG.exe
└ MyPG.jar
execMyPG.bat
set MYPG=???
set DEPEND_PG=???
set OUT_DIR=C:\Users\%username%\Desktop
:: 引数0 -> 依存プログラム, 引数1 -> 出力ディレクトリ
java -jar %MYPG% %DEPEND_PG% %OUT_DIR%
???部分に相対パスとして set MYPG=MyPG.jar
, set DEPEND_PG=Dependency\OtherPG.exe
のように書いてしまうと、batファイルをダブルクリックして起動するときには問題ないが、別の場所からコマンドプロンプトで実行したりタスクスケジューラから実行したりすると、パス指定がおかしくなり動かない。
フォルダの配置場所をCドライブ直下等に決め打ちして、 set MYPG=C:\MyPGFolder\MyPG.jar
とすると、場所が変わった時に動かない汎用性のないものになってしまう。
対策法は、batファイル起動中に、batファイル自身がいる場所をコマンドにより取得して、パス指定の時はすべてその場所を前につけること。
%~dp0
でbatファイル自身がいる場所を取得できる。
コマンドの意味は、http://pentan.info/server/windows/cmd/dp0.htmlに詳細に説明されている。
%0
実行されているファイルのパスです。~
"(ダブルクオート)を除くd
ドライブ文字だけに展開するp
ファイル名を除くパスの部分に展開するつまり%~dp0 は、『実行されているファイルが置かれているカレントディレクトリ』を表します。
オプション構文はcallのヘルプで詳しく説明されています。
execMyPG.bat
set MYDIR=%~dp0
set MYPG=%MYDIR%MyPG.jar
set DEPEND_PG=%MYDIR%Dependency\OtherPG.exe
set OUT_DIR=C:\Users\%username%\Desktop
:: 引数0 -> 依存プログラム, 引数1 -> 出力ディレクトリ
java -jar %MYPG% %DEPEND_PG% %OUT_DIR%
ちなみに、batファイルの初めに cd /d %~dp0
をして、各パスはフルパスではなく相対パスで設定する方法もあるが、batファイルが終了したときのカレントディレクトリが変わってしまうのでお勧めできない。
参考:Linuxで同じことをするには $(dirname $(readlink -f $0))
シェルスクリプト自身のディレクトリの絶対パスを取得する