Arquivo em lote não processando variável em loop

0

Estou trabalhando para melhorar esse arquivo em lote. Meu objetivo é que ele pare o primeiro serviço na lista e espere até que ele pare completamente ou mate-o se ele não parar rapidamente, inicie-o novamente e aguarde até que o serviço seja totalmente iniciado antes de parar o próximo serviço na lista.

Como mostrado neste exemplo, ele primeiro grava o nome de cada serviço em um arquivo, depois lê-o. Ele deve colocá-los no campo %% a, mas em vez disso, colocar em Service_% a como o nome do serviço e, em seguida, falhar.

Como posso alterá-lo para que ele leia o nome correto?

@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
    
por Brian Henson 20.08.2015 / 20:54

1 resposta

0
echo 3050 >> services
         ^              remove this evil space

porque, embora sc query "Service_3050" possa funcionar, sc query "Service_3050 " com esse espaço adicional gerará o próximo erro:

[SC] EnumQueryServicesStatus:OpenService FAILED 1060:

The specified service does not exist as an installed service.

Existe outro erro severo em seu código: usando :label dentro um bloco de código ( entre parênteses ) quebrará um contexto de loop for . Use call :label da seguinte forma:

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

Recursos (leitura obrigatória):

por 21.08.2015 / 03:24