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

Как показано в этом примере, он сначала записывает имя каждой службы в файл, а затем читает их. Следует поместить их в поле %% a, но вместо этого он помещает Service_% a в качестве имени службы, а затем завершается ошибкой.

Как я могу изменить это так, чтобы это читало правильное имя?

@ECHO OFF
SETLOCAL EnableDelayedExpansion
ECHO ---------------------------------------------->> log.txt
ECHO -----------========================----------->> log.txt
ECHO -----------=========%date%=========----------->> log.txt
ECHO -----------========================----------->> log.txt
ECHO ---------------------------------------------->> log.txt

set DD=0
Set TIMESTAMP="eol=; tokens=1,2,3,4* delims=/, "
For /F %TIMESTAMP% %%i in ('DATE /t') DO (
  SET YYYYMMDD=%%l%%j%%k
  SET YYYYMM=%%l%%j
  set DD=%%k
)

echo 3050 >> services
echo 3051 >> services
echo 3052 >> services

for /f %%a in (services) do (
  set timestamp=!date!!time!
  ECHO !timestamp! - Stopping Service %%a >> log.txt
  sc stop Service_%%a >> log.txt
  timeout /t 15 > NUL
  for /f "tokens=4" %%s in ('sc query "Service_%%a" ^| find "STATE"') do if NOT "%%s"=="STOPPED" goto ForceStop
  goto Start

  :ForceStop
  ECHO !timestamp! - Service could not be stopped, forcing... >> log.txt
  taskkill /f /im Service_%%a.exe >> log.txt

  :Start
  ECHO !timestamp! - Service is stopped >> log.txt

  timeout /t 5 > NUL

  set timestamp=!date!!time!
  ECHO !timestamp! - Starting Service %%a >> log.txt
  sc start "Service_%%a" >> log.txt

  :WAIT
  ECHO !timestamp! - Service not yet started >> log.txt
  timeout /t 5 > NUL
  for /f "tokens=4" %%s in ('sc query "Service_%%a" ^| find "STATE"') do if NOT "%%s"=="RUNNING" goto WAIT
  ECHO !timestamp! - Service is started >> log.txt  
)
if exist services del services

1 ответ1

0
echo 3050 >> services
         ^              remove this evil space

поскольку sc query "Service_3050" может работать, sc query "Service_3050 " с таким дополнительным пространством вызовет следующую ошибку:

[SC] EnumQueryServicesStatus:OpenService FAILED 1060:

The specified service does not exist as an installed service.

В вашем коде есть еще одна серьезная ошибка: использование :label внутри ( блок кода в скобках ) нарушит контекст цикла for . Вместо этого используйте call :label следующим образом:

for /f %%a in (services) do (
  set timestamp=!date!!time!
  ECHO !timestamp! - Stopping Service %%a >> log.txt
  sc stop Service_%%a >> log.txt
  timeout /t 15 > NUL
  for /f "tokens=4" %%s in ('
        sc query "Service_%%a" ^| find "STATE"
        ') do if NOT "%%s"=="STOPPED" CALL :ForceStop "%%a%

  ECHO !timestamp! - Service is stopped >> log.txt

  timeout /t 5 > NUL

  set timestamp=!date!!time!
  ECHO !timestamp! - Starting Service %%a >> log.txt
  sc start "Service_%%a" >> log.txt

    call :WAIT "%%a%
)
goto :done

:WAIT
ECHO !timestamp! - Service not yet started >> log.txt
timeout /t 5 > NUL
for /f "tokens=4" %%s in ('
    sc query "Service_%~1" ^| find "STATE"
    ') do if NOT "%%s"=="RUNNING" goto :WAIT
ECHO !timestamp! - Service is started >> log.txt  
exit /B

:ForceStop
ECHO !timestamp! - Service could not be stopped, forcing... >> log.txt
taskkill /f /im Service_%~1.exe >> log.txt
exit /B

:done
if exist services del services

Ресурсы (требуется чтение):

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .