将管道重定向到 Windows 批处理文件中的变量

Nas*_*ign 10 windows batch-file

我想在批处理文件中使用 Windows 命令行从远程 PC 停止和启动 Windows 服务。

sc \\192.168.1.1 stop <ServiceName>

rem sc \\192.168.1.1 query <ServiceName> | findstr STATUS | SET VAR=
Run Code Online (Sandbox Code Playgroud)

但是,我想等到服务的状态确定为停止或启动。所以我打算循环并不断检查状态,直到状态为 STOPPED。

我认为对服务器的重复请求可能是处理器密集型的,但除了检查时间的一些技巧外,无需等待命令行。但我的主要问题是如何获取 Windows 服务的状态,以便我可以使用 IF 语句检查是否可以继续执行下一个命令?

Bob*_*Bob 14

要将变量设置为命令的输出,请使用for /f

for /f "tokens=*" %%a in ('command') do set _CmdResult=%%a
Run Code Online (Sandbox Code Playgroud)

问题是,要在命令中使用管道,您需要使用命令行转义字符转义它:^,因此:^|

for /f "tokens=*" %%a in ('sc \\192.168.1.1 query <ServiceName> ^| findstr STATUS') do set _CmdResult=%%a
Run Code Online (Sandbox Code Playgroud)

现在,我不确定您运行的是哪个版本的 Windows,但我sc在 Windows 7上的查询尝试给出了以下输出:

>sc query SamSs
SERVICE_NAME: SamSs
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 4  RUNNING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
Run Code Online (Sandbox Code Playgroud)

这意味着 afindstr STATE将是必需的,它给出了输出:

>sc query SamSs | findstr STATE
        STATE              : 4  RUNNING
Run Code Online (Sandbox Code Playgroud)

现在,在上面的示例中,tokens=*意味着每个标记都设置为变量%%a,其中标记用空格分隔。在这种情况下,您可以使用第三个标记 ( 4) 或第四个标记 ( RUNNING)。顺便说一句,与测试,1对应STOPPED于我。

为方便起见,我将RUNNING在本例中使用字符串。所以我们想要第四个令牌。

for /f "tokens=4" %%a in ('sc \\192.168.1.1 query <ServiceName> ^| findstr STATE') do set _CmdResult=%%a
Run Code Online (Sandbox Code Playgroud)

当然,根据您的sc query输出,您的输出可能略有不同,因此请按照我的方法进行操作并根据需要进行修改。或者在评论中发布您的输出,sc query我会根据需要进行修改。

要检查该值,您可以使用:

if %_CmdResult%==STOPPED (
    REM do something here
)
Run Code Online (Sandbox Code Playgroud)

在你的情况下,循环会像这样。

:loop
for /f "tokens=*" %%a in ('sc \\192.168.1.1 query <ServiceName> ^| findstr STATUS') do set _CmdResult=%%a
if %_CmdResult%==STOPPED (
    sc \\192.168.1.1 start <ServiceName>
    goto endloop
)
timeout /t 5
goto loop
:endloop
Run Code Online (Sandbox Code Playgroud)

请注意,这timeout是一个仅包含在 Windows Vista 和更高版本中的实用程序。Windows XP 可以使用类似 ping 1.1.1.1 -n 1 -w 5000 > nul.