Пакетний файл не обробляє змінну для циклу


0

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

Як показано в цьому прикладі, він спочатку записує ім'я кожної служби у файл, а потім читає їх. Потрібно розміщувати їх у полі %%, але замість цього він вводить 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

Відповіді:


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

Ресурси (обов'язкове читання):


Добре, це мене зблизило. Тепер проблема, з якою я стикаюся, полягає в тому, що за межами циклу for for значення з файлу служб не переноситься. Сервіс %% a відображається як Service% поза першою для циклу.
Брайан Хенсон

@BrianHenson Mea culpa, mea culpa, mea maxima culpa!
JosefZ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.