サービスが実行されていない場合に、バッチファイルを介してサービスが実行されているかどうかを確認して開始する方法


90

次の操作を実行するバッチファイルを作成します。

  • サービスが実行されているかどうかを確認する
    • 実行中の場合は、バッチを終了します
    • 実行されていない場合は、サービスを開始します

これまでグーグルで処理したコードサンプルは機能しないことが判明したため、投稿しないことにしました。

サービスの開始は、次の方法で行われます。

net start "SERVICENAME"
  1. サービスが実行されているかどうか、およびバッチファイルでifステートメントを作成する方法を確認するにはどうすればよいですか?
  2. 私は少し混乱しています。ネットスタートに引き渡さなければならない議論は何ですか?サービス名またはその表示名?

3
汚いプログラミング:サービスが実行されていない場合にサービスを開始するだけの場合は、開始コマンドを発行するだけです。実行されていない場合は、サービスを開始します。エラーメッセージが表示されるよりもサービスが実行されている場合、サービスは実行されています(停止しません)。汚れていますが動作します。ただし、サービスを開始する必要がある場合にのみ他のコメントを実行する場合は、lcのクリーナーバージョンを使用してください。
Peter Schuetze

@Peter Schuetze:ええ、サービスを開始することが唯一の目的なら、あなたの反対は正しいです。ロギングの開始なども含めたので、lcの解決策を採用しました。
シトロナス2012年

回答:


163

サービスの状態を確認するには、を使用しますsc query <SERVICE_NAME>。バッチファイルのifブロックについては、ドキュメントを確認してください

次のコードは、サービスのステータスをチェックし、MyServiceName実行されていない場合は開始します(サービスが実行されていない場合はifブロックが実行されます)。

for /F "tokens=3 delims=: " %%H in ('sc query "MyServiceName" ^| findstr "        STATE"') do (
  if /I "%%H" NEQ "RUNNING" (
   REM Put your code you want to execute here
   REM For example, the following line
   net start "MyServiceName"
  )
)

それが何をするかの説明:

  1. サービスのプロパティを照会します。
  2. 「STATE」というテキストを含む行を検索します
  3. その行をトークン化し、3番目のトークンを引き出します。これは、サービスの状態を含むトークンです。
  4. 文字列「RUNNING」に対して結果の状態をテストします

2番目の質問については、渡す引数net startはサービス名であり、表示名ではありません


驚くばかり。がんばってくれてありがとう。残念ながらそれは動作しませんか?多分私はこれには愚かです。テストとして「MyServiceName」を「SCardSvr」(エスケープ)に置き換え、すべてをバッチファイルに入れて実行しましたが、サービスが起動しません。net startをファイルに出力するなどの別のものに置き換えても、実行されません。もう一度見てください。=)
シトロナ

おっと、最初の行に余分なものがいくつかありました...これを試してください。それが機能しない場合sc query "SCardSvr"、コマンドラインから実行するとどうなりますか?
lc。

1
「SCardSvr」を引用符で囲んでいますか?私はそれがあるべきだとは思わない
LittleBobbyTables-Au Revoir 2010年

@LittleBobbyTables:その通りです。引用符がなければそれは機能しました。私はとても愚かです:-| ご協力ありがとうございます
シトロナス

@マーク注意してください。その文字列をターゲットOS言語に必要なものに置き換える必要があると思います。「ランニング」も想定しています。
lc。

34

サービスを切り替えるには、以下を使用します。

NET START "分散トランザクションコーディネーター" || NET STOP "分散トランザクションコーディネーター"


1
最初からの終了コードのために機能します。開始コマンドが失敗した場合、それはおそらくすでに実行されているためであり(そしていずれにしても、その後停止しても問題はありません)、それを停止してみてください。
lc。

3
コマンドは、net startが失敗した場合は(||が原因で)停止するように構成されていますが、net startが実行された場合は、net stopは実行されません。鮮やかさ!
ドクターDOS

1
これは私の意見では最良の答えです。多分、@ citronasは、それを承認済みの回答としてマークすることを検討する必要があります。シンプルでスマートでエレガントで、StackOverflowのようなサイトに適合します。それを簡単に!
ソパラホデアリエーレス

2
細心の注意を払う必要はありませんが(OK、少しだけかもしれません)、||実際にはOR演算子ですが、この場合は機能的ELSEステートメントです。これは微妙ですが、重要な違いです。それでも私の+1は得られました-私はこれを常にUnix / Linuxシェルスクリプトで行っていますが、Windowsバッチでこれを行うことを決して考えなかった理由がわかりません。
Doug R.

これは危険すぎるほど単純化されているようです。バッチ処理で自動化したり、他の人に使用を依頼したりするためにそれを使いたくありません...しかし、必要なサービスのために自分のデスクトップに配置できるクイックアイコンを医師が注文しただけです。時々すばやく切り替えます。
Joel Coehoorn 2017

19

次のコマンドを使用して、サービスが実行されているかどうかを確認できます。

sc query [ServiceName] | findstr /i "STATE"

NOD32アンチウイルスで実行すると、次のようになります。

STATE                       : 4 RUNNING

それが停止した場合、私は次のようになります。

STATE                       : 1 STOPPED

これを変数で使用して、NET STARTを使用するかどうかを決定できます。

サービス名は、表示名ではなく、サービス名にする必要があります。


1
あなたの助けをありがとう、あなたが投稿したものを統合しようとしている間、私は私のバッチスキルを大幅に向上させます;)
citronas


10

言語に依存しないバージョン。

@Echo Off
Set ServiceName=Jenkins


SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(
    echo %ServiceName% not running 
    echo Start %ServiceName%

    Net start "%ServiceName%">nul||(
        Echo "%ServiceName%" wont start 
        exit /b 1
    )
    echo "%ServiceName%" started
    exit /b 0
)||(
    echo "%ServiceName%" working
    exit /b 0
)

うん!「宇宙」はいつも背中を急に叩く!
Dr.eel

2
ほぼ完璧な答えです。この行を修正します。Netstart "%ServiceName%"> nul ||(
Cesar

スクリプトをユニバーサルにしたので、Windowsスケジューラタスクで使用できます。と置き換えSet ServiceName=JenkinsSet ServiceName=%~1、次のように呼び出しますwatch-service.bat "Jenkins"
Dr.eel

@ Ant_222言語に依存する「query」の代わりに「queryex」を使用します。そして、なぜそれがWindowsバッチではないと思うのですか?使ってみましたか?
Dr.eel 2017

5

私はこのスレッドを見つけただけで、その人がバッチファイルを使用してサービスを再起動したくない場合は、ディスカッションに追加したいと思いました。Windowsでは、[サービス]、[サービスのプロパティ]、[回復]の順に移動するオプションがあります。ここでは、サービスのパラメータを設定できます。サービスが停止した場合にサービスを再起動したい。また、コンピュータを再起動する場合とは異なる、2回目の失敗の試みを行うこともできます。


2
これは便利な回答ですが、サービスがexit(-1)で停止した場合にのみ機能することに注意してください。サービスが正常に終了した場合(エラーメッセージが表示されても)、自動回復はトリガーされません。また、サービスがユーザーによって手動で強制終了された場合もトリガーされません。
Art Gertner 2016年

@sagelightning:この方法を試すには、管理者権限が必要です。
Kumar M

@ArtGertner-(タスクマネージャーを介して)サービスプロセスを強制終了すると、「クラッシュ」と解釈され、回復がトリガーされます。
マーティンBa

3

Cuando seはWindows enEspañol、elcódigodebe quedar asiを使用します(スペイン語でWindowsを使用する場合、コードは次のとおりです):

for /F "tokens=3 delims=: " %%H in ('sc query MYSERVICE ^| findstr "        ESTADO"') do (
  if /I "%%H" NEQ "RUNNING" (
    REM Put your code you want to execute here
    REM For example, the following line
    net start MYSERVICE
  )
)

Reemplazar MYSERVICE con el nombre del servicio que se desea procesar。Puedes ver el nombre del servicio viendo las propiedades del servicio。(MYSERVICEは、処理するサービスの名前に置き換えます。サービスの名前は、サービスのプロパティで確認できます。)


10
答えを英語で書けば誰にとっても良いでしょう。
j0k

2
なぜ反対票かはわかりません。これは重要なポイントであり、可能であれば文字列の比較を回避する理由です。この場合、ターゲットWindowsインストールのデフォルト言語に応じて文字列を変更する必要があります。
lc。

2
@lc:各言語の回答を含めることは理にかなっていますか?特定の言語を検索するための文字列を示すリソースを参照(または含める)する方が便利な場合があります。
マイクベイリー2013年

2
@echo off

color 1F


@sc query >%COMPUTERNAME%_START.TXT


find /I "AcPrfMgrSvc" %COMPUTERNAME%_START.TXT >nul

IF ERRORLEVEL 0 EXIT

IF ERRORLEVEL 1 NET START "AcPrfMgrSvc"

2

以下のWindowsサーバー2012は私のために働いたものです。「SERVICENAME」のみを実際のサービス名に置き換えます。

@ECHO OFF
SET SvcName=SERVICENAME

SC QUERYEX "%SvcName%" | FIND "STATE" | FIND /v "RUNNING" > NUL && (
    ECHO %SvcName% is not running 
    ECHO START %SvcName%

    NET START "%SvcName%" > NUL || (
        ECHO "%SvcName%" wont start 
        EXIT /B 1
    )
    ECHO "%SvcName%" is started
    EXIT /B 0
) || (
    ECHO "%SvcName%" is running
    EXIT /B 0
)

1

また、サービスがこのように開始された場合にメールを送信したかったので、@ Icコードに少し追加して、誰かに役立つ場合に備えて投稿するつもりだと思っていました。SendMailを使用しましたが、他のコマンドラインオプションがあります。Windowsバッチファイルから簡単なメールを送信する方法は?

set service=MyServiceName

for /F "tokens=3 delims=: " %%H in ('sc query %service% ^| findstr "        STATE"') do (
  if /I "%%H" NEQ "RUNNING" (

    net start %service%

    for /F "tokens=3 delims=: " %%H in ('sc query %service% ^| findstr "        STATE"') do (
      if /I "%%H" EQ "RUNNING" (
        SendMail /smtpserver localhost /to me@mydomain.com /from watchdog@mydomain.com /subject Service Autostart Notification /body Autostart on service %service% succeded.
      ) else (
        SendMail /smtpserver localhost /to me@mydomain.com /from watchdog@mydomain.com /subject Service Autostart Notification /body Autostart on service %service% failed.
      )
    )

  )
)

1

Powershellスクリプトを使用してサービスを開始します。これをタスクスケジューラにリンクして、定期的または必要に応じてトリガーできます。これをPS1ファイル、つまり拡張子がPS1のファイルとして作成し、このファイルをタスクスケジューラからトリガーします。

サービスを停止するには

タスクスケジューラでサーバーで使用している場合は、これを引数で使用します

-noprofile -executionpolicy bypass -file "C:\ Service Restart Scripts \ StopService.PS1"

cmdでも同じように実行して、動作するかどうかを確認します。タスクスケジューラでも動作するはずです。

$Password = "Enter_Your_Password"
$UserAccount = "Enter_Your_AccountInfor"
$MachineName = "Enter_Your_Machine_Name"
$ServiceList = @("test.SocketService","test.WcfServices","testDesktopService","testService")
$PasswordSecure = $Password | ConvertTo-SecureString -AsPlainText -Force
$Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $UserAccount, $PasswordSecure 

$LogStartTime = Get-Date -Format "MM-dd-yyyy hh:mm:ss tt"
$FileDateTimeStamp = Get-Date -Format "MM-dd-yyyy_hh"
$LogFileName = "C:\Users\krakhil\Desktop\Powershell\Logs\StartService_$FileDateTimeStamp.txt" 


#code to start the service

"`n####################################################################" > $LogFileName
"####################################################################" >> $LogFileName
"######################  STARTING SERVICE  ##########################" >> $LogFileName

for($i=0;$i -le 3; $i++)
{
"`n`n" >> $LogFileName
$ServiceName = $ServiceList[$i]
"$LogStartTime => Service Name: $ServiceName" >> $LogFileName

Write-Output "`n####################################"
Write-Output "Starting Service - " $ServiceList[$i]

"$LogStartTime => Starting Service: $ServiceName" >> $LogFileName
Start-Service $ServiceList[$i]

$ServiceState = Get-Service | Where-Object {$_.Name -eq $ServiceList[$i]}

if($ServiceState.Status -eq "Running")
{
"$LogStartTime => Started Service Successfully: $ServiceName" >> $LogFileName
Write-Host "`n Service " $ServiceList[$i] " Started Successfully"
}
else
{
"$LogStartTime => Unable to Stop Service: $ServiceName" >> $LogFileName
Write-Output "`n Service didn't Start. Current State is - "
Write-Host $ServiceState.Status
}
}

#code to stop the service

"`n####################################################################" > $LogFileName
"####################################################################" >> $LogFileName
"######################  STOPPING SERVICE  ##########################" >> $LogFileName

for($i=0;$i -le 3; $i++)
{
"`n`n" >> $LogFileName
$ServiceName = $ServiceList[$i]
"$LogStartTime => Service Name: $ServiceName" >> $LogFileName

Write-Output "`n####################################"
Write-Output "Stopping Service - " $ServiceList[$i]

"$LogStartTime => Stopping Service: $ServiceName" >> $LogFileName
Stop-Service $ServiceList[$i]

$ServiceState = Get-Service | Where-Object {$_.Name -eq $ServiceList[$i]}

if($ServiceState.Status -eq "Stopped")
{
"$LogStartTime => Stopped Service Successfully: $ServiceName" >> $LogFileName
Write-Host "`n Service " $ServiceList[$i] " Stopped Successfully"
}
else
{
"$LogStartTime => Unable to Stop Service: $ServiceName" >> $LogFileName
Write-Output "`nService didn't Stop. Current State is - "
Write-Host $ServiceState.Status
}
}

0
@Echo off

Set ServiceName=wampapache64

SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(

echo %ServiceName% not running
echo  

Net start "%ServiceName%"


    SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(
        Echo "%ServiceName%" wont start
    )
        echo "%ServiceName%" started

)||(
    echo "%ServiceName%" was working and stopping
    echo  

    Net stop "%ServiceName%"

)


pause

0

@DanielSerranoの回答に関連して、私は最近、sc.exeコマンドのローカライズ、つまりスペイン語に少し触れました。私の提案は、数値のサービス状態を保持するラインとトークンを特定し、それを解釈することです。

@echo off

rem TODO: change to the desired service name
set TARGET_SERVICE=w32time

set SERVICE_STATE=
rem Surgically target third line, as some locales (such as Spanish) translated the utility's output
for /F "skip=3 tokens=3" %%i in ('""%windir%\system32\sc.exe" query "%TARGET_SERVICE%" 2>nul"') do (
  if not defined SERVICE_STATE set SERVICE_STATE=%%i
)
rem Process result
if not defined SERVICE_STATE (
  echo ERROR: could not obtain service state!
) else (
  rem NOTE: values correspond to "SERVICE_STATUS.dwCurrentState"
  rem https://msdn.microsoft.com/en-us/library/windows/desktop/ms685996(v=vs.85).aspx
  if not %SERVICE_STATE%==4 (
    echo WARNING: service is not running
    rem TODO: perform desired operation
    rem net start "%TARGET_SERVICE%"
  ) else (
    echo INFORMATION: service is running
  )
)

テスト済み:

  • Windows XP(32ビット)英語
  • Windows 10(32ビット)スペイン語
  • Windows 10(64ビット)英語

0

多分もっと簡単な方法ですか?ここで回答のリストに追加するだけです:

@for /f "tokens=1,* delims=: " %%a in ('sc queryex state=Inactive') do net start "%%b"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.