批量停止服务不会做任何事情

时间:2018-05-10 20:08:05

标签: windows batch-file service

我在这里遇到一个奇怪的错误。我有一个批处理脚本,用于部署应用程序文件和启动服务。在该脚本中,我使用一些批处理来检查服务是否已经运行,并提示用户在需要时停止它。检查和提示工作正常,但是当我尝试使用它来停止服务时,它什么都不做。它只是跳过下一步而没有任何错误。

完整批量脚本:

@echo off

set WILDFLY_DIR=path\to\wildfly\deploy\dir
set JBOSS_DIR=path\to\jboss\deploy\dir 
set EAR_DIR=path\to\ear\file\parent\dir
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

我遇到问题的具体部分是:

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

这是问题发生时的输出:

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....

当它工作时,输出将如下所示:

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....

我确保检查区分大小写,因此它应该接受y或Y.它会随机跳过此步骤并直接删除现有的EAR文件。我无法弄清楚原因。

有没有人知道造成这种情况的原因是什么?

---- ---- EDIT

正如Michael Heath在下面的答案中指出的那样,这是一个延迟扩张的问题。我能够通过修改批处理文件的问题部分来解决问题,如下所示:

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

2 个答案:

答案 0 :(得分:1)

您没有使用setlocal,因此变量不是 脚本本地。

我看到停止服务的唯一方法是重启 同一个CMD会话中的脚本。

正如Squashman评论的那样,不使用“延迟扩展” 一个问题。 如果您使用echo on运行脚本,则可能会看到此内容 可能会看到"%STOP_WILDFLY%" == "Y"评估为"" == "Y" 即使你输入了一些文字。

以下是test.cmd中的示例代码块。代码块 是从开放(到结束)的CMD解析。 一行中可存在多组(),即 if ""=="" (...) else (...)可能跨越多个 脚本中的文字行。

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

CMD将解析该代码块并解释为1行 在您回答之前,将对%reply%进行评估 输入提示。

运行test.cmd两次,您可能会看到:

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"

所以现在你可能知道为什么它有时会起作用,有时却不起作用。

除非您想保留变量,否则请在脚本中使用setlocal 在同一个CMD会话中执行脚本之后。类型 {CM}提示setlocal /?提供更多帮助。

通过在CMD提示符下键入set /?来研究“延迟扩展”。

答案 1 :(得分:0)

您不是在等待服务停止。您需要循环,直到服务状态停止。 See my previous answer to a very similar problem。寻找:StoppedWait