Как проверить, запущена ли служба через пакетный файл и запустить ее, если она не запущена?

Я хочу написать пакетный файл, который выполняет следующие операции:

  • Проверьте, работает ли служба
    • Если он запущен, закройте пакет
    • Если он не запущен, запустите службу

Образцы кода, которые я искал в Google, пока не работают, поэтому я решил не публиковать их.

Запуск службы выполняется с помощью:

net start "SERVICENAME"
  • Как проверить, работает ли служба, и как сделать оператор if в пакетном файле?
  • Я немного смущен. Каков аргумент, который я должен передать в начало сети? Имя службы или ее отображаемое имя?

Ответ 1

Чтобы проверить состояние службы, используйте sc query <SERVICE_NAME>. Если блоки в пакетных файлах, проверьте документацию.

Следующий код проверит состояние службы 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"

Что касается вашего второго вопроса, аргумент, который вы хотите передать net start это имя службы, а не отображаемое имя.

Ответ 2

Для переключения службы используйте следующее:

NET START "Распределенная транзакция Координатор" NET STOP "Распределенный Координатор транзакций"

Ответ 3

Вы можете использовать следующую команду, чтобы узнать, работает ли служба:

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

Когда я запускаю его для своего NOD32 Antivirus, я получаю:

STATE                       : 4 RUNNING

Если он был остановлен, я бы получил:

STATE                       : 1 STOPPED

Вы можете использовать это в переменной, чтобы определить, используете ли вы NET START или нет.

Имя службы должно быть именем службы, а не отображаемым именем.

Ответ 4

Это должно сделать это:

FOR %%a IN (%Svcs%) DO (SC query %%a | FIND /i "RUNNING"
IF ERRORLEVEL 1 SC start %%a)

Ответ 5

Независимая от языка версия.

@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
)

Ответ 6

Я только что нашел этот поток и хотел добавить к обсуждению, если человек не хочет использовать пакетный файл для перезапуска служб. В Windows есть опция, если вы перейдете к услугам, свойствам службы, а затем восстановлению. Здесь вы можете установить параметры для службы. Как перезапустить службу, если служба остановится. Кроме того, вы можете даже выполнить вторую попытку сбоя сделать что-то другое, как при перезагрузке компьютера.

Ответ 7

Взаимодействие с Windows en Español, el código debe 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 с энтузиазмом и профессионализмом. Puedes ver el nombre del servicio viendo las propiedades del servicio. (Замените MYSERVICE на имя обрабатываемой услуги. Вы можете увидеть имя службы в свойствах службы.)

Ответ 8

@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"

Ответ 9

Я также хотел отправить электронное сообщение, если служба была запущена таким образом, так что добавленный бит в код @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 [email protected] /from [email protected] /subject Service Autostart Notification /body Autostart on service %service% succeded.
      ) else (
        SendMail /smtpserver localhost /to [email protected] /from [email protected] /subject Service Autostart Notification /body Autostart on service %service% failed.
      )
    )

  )
)

Ответ 10

Запуск службы с использованием Powershell script. Вы можете связать это с планировщиком задач и запустить его с интервалом или по мере необходимости. Создайте это как файл 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
}
}

Ответ 11

@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

Ответ 12

В связи с ответом @DanielSerrano, меня недавно немного sc.exe локализация команды 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 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-разрядная версия) английский

Ответ 13

Может быть, гораздо проще? Просто добавив в список ответов здесь:

@for /f "tokens=1,* delims=: " %%a in ('sc queryex state=Inactive') do net start "%%b"

Ответ 14

Для Windows server 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
)