はじめに
ネットワーク設定を変えることが増えて、いちいちインターフェースを右クリックしてプロパティ開いて、、という作業を減らしたかった。
batの知識はほぼゼロからでした。
参考
ほとんどこちらのコピペです。ありがとうございます。
設定するネットワーク環境
「ワイヤレス ネットワーク接続」に
IPアドレス:192.168.11.90
マスク:255.255.255.0
GW:192.168.11.1
DNS1:192.168.11.1
と設定することにする。
追記していく方法
参考元の例では渡す処理が1つのコマンド(mkdir)だけだが、複数のコマンドを渡すときには工夫が必要になる。
複数コマンドを&で並べずに、一行ずつsyori.batに追記していく方法だと遅延環境変数とかエスケープとか考えずにすむ。
set syori_1=netsh interface ipv4 set address %IFNAMEWL% static %IPADDR% %MASK% %GW%
set syori_2=netsh interface ipv4 set dnsservers %IFNAMEWL% %DNS1%
rem セットしたコマンドをbatに出力する。2行目は「>>」で追記する
echo %syori_1% >syori.bat
echo %syori_2% >>syori.bat
が、2行程度ならまだしももっと増えた場合めんどくさすぎるので、以下の方法をとった。
最終的なソースコード
@echo off
rem 日時を取得する
set now_date=%DATE: =0%
set now_date=%now_date:~0,4%%now_date:~5,2%%now_date:~8,2%
set now_time=%time: =0%
set now_time=%now_time:~0,2%%now_time:~3,2%%now_time:~6,2%
set now_dt=%now_date%%now_time%
rem 場所の移動する
cd /d "%~dp0"
rem ネットワーク設定
set IFNAMEWL="ワイヤレス ネットワーク接続"
set IPADDR=192.168.11.90
set MASK=255.255.255.0
set GW=192.168.11.1
set DNS1=192.168.11.1
rem 実行したい処理をセットする。& で複数コマンド。&をリテラルで渡すには^& と書いて渡す。
setlocal ENABLEDELAYEDEXPANSION
set syori_1=netsh interface ipv4 set address %IFNAMEWL% static %IPADDR% %MASK% %GW% ^& netsh interface ipv4 set dnsservers %IFNAMEWL% %DNS1%
rem セットしたコマンドをbatに出力する。出力直前に変数を展開する
echo !syori_1!>syori.bat
rem デバッグ用
type syori.bat
rem エラーが起きた時の為にエラーレベルを出力する
set syori_err_l=echo %%errorlevel%%
echo %syori_err_l% ^>"%~dp0"err_%now_dt%.log >>syori.bat
rem powershellで管理者権限で出来たbatを実行する
powershell start-process syori.bat -verb runas
rem 処理が終わるまでちょい待つ。自分に2回pingして結果を出力しない。
@ping localhost -n 2 > nul
rem 出力されたエラーレベルを取得する
set /p err_l_get=<./err_%now_dt%.log
rem エラーレベルで処理の成否を判定
if %err_l_get% == 0 (
echo 処理完了!!!
) else (
echo 処理エラー ヘルプに問い合わせて
goto err_go
)
rem 使い終わったbatとlogを消す
del syori.bat
del err_%now_dt%.log
echo キーボードをどれか押すと閉じる
@pause > nul
exit
:err_go
rem エラー時の処理
rem 使い終わったbatを消す
del syori.bat
echo キーボードをどれか押すと閉じる
@pause > nul
exit
ハマリポイント1:&のエスケープ
set syori_1= の行で複数のコマンドを変数に格納するとき、コマンドを&で並べるときに^&と書かないとダメ。
&をリテラルで書くときの注意点。
set syori_1=netsh interface ipv4 set address %IFNAMEWL% static %IPADDR% %MASK% %GW% ^& netsh interface ipv4 set dnsservers %IFNAMEWL% %DNS1%
このエスケープについては割とすぐに気づいた。
ハマリポイント2:遅延環境変数
syori.batにコマンドを出力するとき、はじめはこう書いていた。
echo &syori_1&>syori.bat
文頭の @echo off
をonにして実行時ログを見ると
echo netsh interface ip set address "ワイヤレス ネットワーク接続" static 192.168.11.90 255.255.255.0 192.168.11.1 & netsh interface ip add dns "ワイヤレス ネットワーク接続" 192.168.11.1 1>syori.bat
netsh interface ip set address "ワイヤレス ネットワーク接続" static 192.168.11.90 255.255.255.0 192.168.11.1 // なぜか1つ目のnetshが実行される。
type syori.bat
要求された操作には、権限の昇格が必要です。管理者として実行してください。
// 1つ目のnetshの実行結果が出力されている
調べてみると
Windowsバッチファイル変数
環境変数の展開方法には「%変数%」と「!変数!」の二通りがあります。「%」は構文解析時に環境変数の展開を行い、「!」はコマンド実行の直前に(つまり遅延して)環境変数の展開を行います。
どうやら今回の場合は、変数&syori_1&
が展開するときになんかうまくいかなかったっぽい。
batchの詳しい処理順序とか理解できていませんが。
遅延環境変数を使えばうまくいきました。
setlocal ENABLEDELAYEDEXPANSION
set syori_1=netsh interface ip set address %IFNAMEWL% static %IPADDR% %MASK% %GW% ^& netsh interface ip add dns %IFNAME% %DNS1%
echo !syori_1!>syori.bat
実行時ログ
echo !syori_1! 1>syori.bat
//echo実行時では変数は格納されたまま、出力直前で展開される。
type syori.bat
netsh interface ip set address "ワイヤレス ネットワーク接続" static 192.168.11.90 255.255.255.0 192.168.11.1 & netsh interface ip add dns "ワイヤレス ネットワーク接続" 192.168.11.1
おわり
素直に右クリックメニューから管理者として実行すればいいんだけどね。