我想使用 Windows 命令行在批处理文件中从远程 PC 停止和启动 Windows 服务。
sc \\192.168.1.1 stop <ServiceName>
rem sc \\192.168.1.1 query <ServiceName> | findstr STATUS | SET VAR=
但是,我想等到服务状态确定后再停止或启动。所以我计划循环并不断检查状态,直到状态为 STOPPED。
我认为对服务器的重复请求可能会占用大量处理器资源,但除了一些检查时间的技巧外,命令行无需等待。但我的主要问题是如何获取 Windows 服务的状态,以便我可以使用 IF 语句检查是否可以继续执行下一个命令?
答案1
要将变量设置为命令的输出,请使用for /f
:
for /f "tokens=*" %%a in ('command') do set _CmdResult=%%a
问题是,要在命令中使用管道,您需要使用命令行转义字符对其进行转义:^
,因此:^|
。
for /f "tokens=*" %%a in ('sc \\192.168.1.1 query <ServiceName> ^| findstr STATUS') do set _CmdResult=%%a
现在,我不确定您正在运行哪个版本的 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
这意味着findstr STATE
需要一个,从而给出输出:
>sc query SamSs | findstr STATE
STATE : 4 RUNNING
现在,在上面的例子中,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
当然,根据您的sc query
输出,您的输出可能会略有不同,因此请按照我的方法进行修改。或者在评论中发布您的输出,sc query
我会根据需要进行修改。
要检查该值,您可以使用:
if %_CmdResult%==STOPPED (
REM do something here
)
在你的情况下,循环将会是这样的。
: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
请注意,这timeout
是仅包含在 Windows Vista 及更高版本中的实用程序。Windows XP 可以使用就像是 ping 1.1.1.1 -n 1 -w 5000 > nul
。
答案2
复杂程度更高的更高级示例
(但可用性也更高)
- 使用几个常见的应用程序(
cURL
,,),GREP
你可以下载这些应用程序的 Win32 预构建版本,也可以使用SED
赛格威Windows 中的 exe 文件-都很好(对于 cygwin,最好将c:\cygwin\bin\
文件夹位置放在系统PATH
变量中以便于访问)。 - PIPE 处理(通过 STDOUT 和 STDERR 进行处理)。
- 转义符号(
|
,,>
) - Windows7+ 上&
的 最佳实践/必需。 - 无循环,没有转到
- 使用数字数据(
curl
响应标头Content-Length
) 和..没有临时文件!
@echo off
setlocal enableextensions
for /f "tokens=*" %%a in ('curl --head --ipv4 --sslv3 --silent --location-trusted --url "https://storage.googleapis.com/chromium-browser-continuous/Win_x64/362418/mini_installer.exe" 2^>^&1 ^| grep "Content-Length" 2^>^&1 ^| sed "s/\r\n$//g" 2^>^&1 ^| sed "s/content-length\:\ //gi" 2^>^&1') do ( set /a num=%%a )
set /a num=%num% / 1024 / 1024
echo it is %num%MB
endlocal
将输出
it is 41MB
(原始标题是Content-Length: 43597312
)