windows - Stop service i batch tilfældigt gør ingenting

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har en mærkelig fejl her. Jeg har et batch script, som jeg bruger til at implementere en applikationsfil og starte en tjeneste. I dette script bruger jeg et parti til at kontrollere, om tjenesten allerede kører, og opfordre brugeren til at stoppe det hvis de vil. Denne check og spørgsmålet virker, men nu og da, når jeg forsøger at bruge den til at stoppe tjenesten, gør det ingenting. Det springer bare til næste trin uden fejl.


Fuld batch script:


@echo off

set WILDFLY\_DIR=path	owildflydeploydir
set JBOSS\_DIR=path	ojbossdeploydir 
set EAR\_DIR=path	oearfileparentdir
set SERVICE\_WILDFLY=WildflyServiceName
set SERVICE\_JBOSS=JBossServiceName
set SERVICE=
set DST=
set SRC=

goto :SEL\_SERVER

:SEL\_SERVER
set /p SERVER="What Application Server (1: Wildfly; 2: JBoss): "
if \%SERVER\% == 1 (
   set DST=\%WILDFLY\_DIR\%
   set SERVICE=\%SERVICE\_WILDFLY\%
) else if \%SERVER\% == 2 (
   set DST=\%JBOSS\_DIR\%
   set SERVICE=\%SERVICE\_JBOSS\%
) else (
   echo Unrecognized Server: \%SERVER\%
   goto :SEL\_SERVER
)
goto :SEL\_VERSION

:SEL\_VERSION
set /p VERSION="What Version: "
IF /I NOT EXIST \%EAR\_DIR\%\%VERSION\% (
   ECHO Unrecognized Version: \%VERSION\%
   goto :SEL\_VERSION
) else (
   set SRC=\%EAR\_DIR\%\%VERSION\%
   goto :DO\_DEPLOY
)

:DO\_DEPLOY
for /F "tokens=3 delims=: " \%\%H in ('sc query \%SERVICE\_WILDFLY\% ^| findstr "        STATE"') do (
   if /I "\%\%H" == "RUNNING" (
     set /p STOP\_WILDFLY="Wildfly 10 Service is running, stop it now? (Y/N) "
     if /I "\%STOP\_WILDFLY\%" == "Y" (
         net stop \%SERVICE\_WILDFLY\%
     )
   )
)
for /F "tokens=3 delims=: " \%\%G in ('sc query \%SERVICE\_JBOSS\% ^| findstr "        STATE"') do (
   if /I "\%\%G" == "RUNNING" (
     set /p STOP\_JBOSS="JBoss 6.1 Service is running, stop it now? (Y/N) "
     if /I "\%STOP\_JBOSS\%" == "Y" (
         net stop \%SERVICE\_JBOSS\%
     )
   )
)
echo Deleting existing EAR file...
FORFILES /p \%DST\% /m MyApplication*.* /c "cmd /c DEL @file"

@echo on
ROBOCOPY \%SRC\% \%DST\% MyApplication*.ear
@echo off
goto :START\_SERVICE

:START\_SERVICE
set /p START="Start Service Now? (Y/N) "

IF /I "\%START\%" == "Y" (
   net start "\%SERVICE\%"
)
goto :SEL\_SERVER


Den specifikke del, jeg har problemer med, er dette:


for /F "tokens=3 delims=: " \%\%H in ('sc query \%SERVICE\_WILDFLY\% ^| findstr "        STATE"') do (
   if /I "\%\%H" == "RUNNING" (
     set /p STOP\_WILDFLY="Wildfly 10 Service is running, stop it now? (Y/N) "
     if /I "\%STOP\_WILDFLY\%" == "Y" (
         net stop \%SERVICE\_WILDFLY\%
     )
   )
)
for /F "tokens=3 delims=: " \%\%G in ('sc query \%SERVICE\_JBOSS\% ^| findstr "        STATE"') do (
   if /I "\%\%G" == "RUNNING" (
     set /p STOP\_JBOSS="JBoss 6.1 Service is running, stop it now? (Y/N) "
     if /I "\%STOP\_JBOSS\%" == "Y" (
         net stop \%SERVICE\_JBOSS\%
     )
   )
)


Dette er outputen, når problemet opstår:


What Application Server (1: Wildfly; 2: JBoss): 1
What Version: 2018.1.1
Wildfly 10 Service is running, stop it now? (Y/N) y
Deleting existing EAR file...

The rest removed for brevity....


Når det virker, ser udgangen sådan ud:


What Application Server (1: Wildfly; 2: JBoss): 1
What Version: 2018.2.1
Wildfly 10 Service is running, stop it now? (Y/N) y
The WildflyServiceName service is stopping...
The WildflyServiceName service was stopped successfully.

Deleting existing EAR file...

the rest removed for brevity....


Jeg sørgede for at tjekke for sårfølsomhed, og det skulle derfor acceptere y eller Y. Det springer tilfældigt bare dette trin og går lige videre til at slette eksisterende EAR-filer. Jeg har ikke kunnet finde ud af hvorfor.


Har nogen nogen ide om, hvad der kan forårsage dette?


----REDIGERE----


Som Michael Heath angav i svaret nedenfor, er dette et forsinket ekspansionsproblem. Jeg kunne løse problemet ved at ændre problemafsnittet i batchfilen som følger:


setlocal enabledelayedexpansion
for /F "tokens=3 delims=: " \%\%H in ('sc query \%SERVICE\_WILDFLY\% ^| findstr "        STATE"') do (
   if /I "\%\%H" == "RUNNING" (
     set /p STOP\_WILDFLY="Wildfly 10 Service is running, stop it now? (Y/N) "
     if /I "!STOP\_WILDFLY!" == "Y" (
         net stop \%SERVICE\_WILDFLY\%
     )
   )
)
for /F "tokens=3 delims=: " \%\%G in ('sc query \%SERVICE\_JBOSS\% ^| findstr "        STATE"') do (
   if /I "\%\%G" == "RUNNING" (
     set /p STOP\_JBOSS="JBoss 6.1 Service is running, stop it now? (Y/N) "
     if /I "!STOP\_JBOSS!" == "Y" (
         net stop \%SERVICE\_JBOSS\%
     )
   )
)
endlocal

Bedste reference


Du bruger ikke setlocal og dermed er variablerne ikke
lokal til scriptet.


Den eneste måde jeg ser på at stoppe en tjeneste er, hvis du genstarter
scriptet i den samme CMD-session.


Som Squashman kommenterede, er det ikke brug af ' forsinket ekspansion '
et problem.
Du kan muligvis se dette, hvis du kører scriptet med echo on og
kan se "\%STOP\_WILDFLY\%" == "Y" evaluere til "" == "Y"
selvom du indtaster nogle tekst.


Her er et eksempel kode blok i test.cmd. En kodeblok
er CMD parsing fra en åbning ( til en lukning ).
Mere end 1 sæt () kan eksistere i en linje, dvs.
if ""=="" (...) else (...) som kunne spænde flere
bogstavelige linjer i scriptet.


(
    set /p "reply=prompt [y|n]: "
    echo "\%reply\%"
)


CMD vil analysere den pågældende blok kode og fortolke som 1 linje
og \%reply\% vil blive evalueret, før du får svaret
input prompt.


Kør test.cmd to gange, og du kan se:


C:> test.cmd

C:> (
set /p "reply=prompt [y|n]: "
 echo ""
)
prompt [y|n]: y
""

C:> test.cmd

C:> (
set /p "reply=prompt [y|n]: "
 echo "y"
)
prompt [y|n]: y
"y"


Så nu kan du vide, hvorfor det nogle gange virker, og nogle gange virker det ikke.


Brug setlocal i scriptet, medmindre du vil beholde variabler
efter udførelsen af ​​scriptet i den samme CMD-session. Type
setlocal /? ved en CMD-prompt for mere hjælp.


Forskning ' forsinket ekspansion ' ved at skrive set /? ved en CMD-prompt.

Andre referencer 1


Du venter ikke på, at tjenesten stopper. Du skal løbe, indtil servicestatus er stoppet. Se mit tidligere svar på et meget lignende problem. Kig efter :StoppedWait.