管理者実行が必要なコマンドをバッチファイルに組み込んだ場合、実行パスが"C:\Windows\System32"に固定されます。
これを"バッチファイルの保管ディレクトリ"を指定するための方法を試してみました。
やりたいこと
netshコマンドのように管理者実行のコマンドプロンプトで実行する必要がある命令を実行するために、バッチファイルを以前<バッチファイルをダブルクリックするだけで管理者で実行する - treedown’s Report>で管理者実行されるようにバッチファイルを構成しました。
ただ、この管理者実行をした場合、実行パス(カレントディレクトリ)が"C:\Windows\System32"に固定されるため、今回USBメモリなどのドライブレターが変動するパスを上手く解釈したバッチファイルを作成する必要があったので、試行錯誤することになりました。
結論:変数「%~dp0」を使う
最初は%CD%を予め変数に入れて…とかやっていたのですが、再起実行するバッチファイルでは上手く動作しませんでした。
そこで「%~dp0」の出番でした。こういうときに使う変数です。
試しにやってみる
さっそくやってみます。
USBドライブ(ここではD:)にsample.batを作成して、Windowsコマンドプロンプトで実行してみます。
このD:はUSBメモリを接続するPC環境によって変化しますので、このD:の部分が変わっても動作するようにしたい、というのが今回のサンプルの目的です。
サンプルバッチファイルは以下のようにしてみました。
--------------------------------------------------------------
サンプルバッチファイル
--------------------------------------------------------------
@echo off
rem 管理者権限で実行されているかどうかを確認して実行
whoami /priv | find "SeSystemtimePrivilege" > nul
if %errorlevel% neq 0 (
powershell -command start-process %~0 -verb runas
exit
)
echo 現在のディレクトリは%CD%
echo %~0
echo %~d0
echo %~p0
echo バッチファイルの保管ディレクトリは%~dp0
echo .
pushd %~dp0
echo ..
echo 現在のディレクトリは%CD%
echo ...
popd
pause
--------------------------------------------------------------
サンプルバッチの実行と解説
これを実行すると、
このようにechoで指定したそれぞれの表示がコマンドプロンプトで実行されます。
最初のechoで表示した"%CD%"は起動直後のカレントディレクトリである"C:\Windows\System32"となっています。
続いて、"%~0"で参照したパスは"D:\_tools\sample.bat"、"%~d0"は"D:"、"%~p0"は"\_tools\"とそれぞれ表示されています。今回の"%~dp0"で表示するパスが"D:\_tools\"でバッチファイルの保管ディレクトリを参照することができています。
バッチファイルで別のファイルを参照する必要がある今回は、
pushd %~dp0
でカレントディレクトリを"C:\Windows\System32"から"D:\_tools"へ変更し
最期に「popd」で戻るようにしています。
やりたかったこと
今回、管理者実行したバッチファイルで実行したかったのが、
netsh wlan add profile filename=".\Wi-Fi-SSID.xml" user=all
でWi-FiのSSIDを追加するコマンドを実行したかったので
こんな感じでバッチファイルと同じフォルダ内に設定.xmlを置いて、バッチをダブルクリック実行でSSIDが追加されるようにしようと思いました。
しかし、netshは管理者実行が必須、しかし管理者実行でカレントディレクトリが"C:\Windows\System32"となるため、xmlファイルのパス指定で".\"が使えないなぁ、ということから「%~dp0」を使うところに行き着きました。