net stopコマンド後続のバッチコマンドが動かなかった

備忘録ヘッダ画像 プログラミング備忘録

Windowsのサービスプログラムを再起動し、溜まったログやら綺麗にして再起動するバッチファイルが上手く動かなかった時の話です。

以下のような非常にシンプルなバッチファイルを、タスクスケジューラで日に一度実行していたのですが、なぜかnet stop後続のsc startが動作しないことがあるという事象に巡り合いました。

@echo off
setlocal
set service_name="サービスプログラム名"
net stop %service_name%
~定時処理~
sc start %service_name%

再現しづらいというのはやはり厄介な上に、イベントログにもエラーらしき情報は残っておらず、数日間悩みの種となっていました。。。

net stop周りのサービスプログラムの出すログをよく観察していると、後続の処理がこける(終了するだけで起動していない)時は決まってサービスプログラムの終了処理に30秒ほどの時間を要していることに気づきました。

もしやnet stopコマンドにタイムアウトがあって後続のsc startが呼び出される時にはまだサービスが終了していないということなのでは、、、!?

早速バッチファイルを書き直してみました。
ビンゴだったようです。

@echo off
setlocal
set service_name="サービス名"

rem ---------- サービス停止 ----------
:service_stop
echo サービス停止 (%date%  %time%)
echo %%service_name 停止中
sc stop %%s >nul
timeout /t 1 /nobreak >nul
:wait1
sc query %%service_name | find "STOPPED" >nul
if %errorlevel%==1 (
    timeout /t 5 /nobreak >nul
    goto wait1
) else (
    echo %%service_name 停止
    rem サービス停止中に行う定時処理
)

rem ---------- サービス起動 ----------
:service_start
echo サービス起動 (%date%  %time%)
echo %%service_name 起動中
sc start %%service_name >nul
timeout /t 1 /nobreak >nul
:wait2
sc query %%service_name | find "RUNNING" >nul
if %errorlevel%==1 (
    timeout /t 5 /nobreak >nul
    goto wait2
) else (
    echo %%service_name 起動
)

rem 終了
:quit
exit

レジストリの値を書き直すことでタイムアウトの時間そのものを伸ばせるようですが、如何せんレジストリをいじくり回す勇気はなかったです。

タイトルとURLをコピーしました