如何通过批处理文件检查服务是否正在运行,并在其未运行时停止它?

6
我需要一个批处理文件来检查服务"MyServiceName"是否正在运行。如果服务正在运行,我希望批处理文件将其禁用,然后显示一条消息。如果服务未运行且已禁用,则我希望批处理文件显示一条消息,然后退出。感谢您的帮助。
3个回答

11
sc query MyServiceName| find "RUNNING" >nul 2>&1 && echo service is runnung
sc query MyServiceName| find "RUNNING" >nul 2>&1 || echo service is not runnung
停止服务:
net stop MyServiceName

2

我尝试编写了一个使用SC命令的小脚本,但似乎存在一些限制(我无法进行测试):

@echo off
setlocal enabledelayedexpansion
:: Change this to your service name
set service=MyServiceName
:: Get state of service ("RUNNING"?)
for /f "tokens=1,3 delims=: " %%a in ('sc query %service%') do (
  if "%%a"=="STATE" set state=%%b
)
:: Get start type of service ("AUTO_START" or "DEMAND_START")
for /f "tokens=1,3 delims=: " %%a in ('sc qc %service%') do (
  if "%%a"=="START_TYPE" set start=%%b
)
:: If running: stop, disable and print message
if "%state%"=="RUNNING" (
  sc stop %service%
  sc config %service% start= disabled
  echo Service "%service%" was stopped and disabled.
  exit /b
)
:: If not running and start-type is manual, print message
if "%start%"=="DEMAND_START" (
  echo Start type of service %service% is manual.
  exit /b
)
:: If start=="" assume Service was not found, ergo is disabled(?)
if "%state%"=="" (
  echo Service "%service%" could not be found, it might be disabled.
  exit /b
)

我不知道这是否符合您的预期行为。似乎SC不会列出已禁用的服务。但是,由于您不想在禁用时执行任何操作,因此我的代码仅在未找到服务时打印一条消息。
然而,您可以将我的代码作为您的目的的框架/工具箱来使用。
编辑:
根据npocmaka的答案,您可以将for部分更改为以下内容:
sc query %service%| find "RUNNING" >nul 2>&1 && set running=true

sc query state= all(等号后面的空格很重要)将获取所有服务。 - mojo
好的,我明白了,谢谢。然而,当你寻找特定名称时,“SC”无论如何都会返回“STATE=STOPPED”,所以你可能也可以测试"%state%"=="STOPPED" - marsze

1
此脚本以服务名称作为第一个(也是唯一的)参数,或者您可以将其硬编码到SVC_NAME指定中。 sc命令的输出被丢弃。我不知道你是否真的想看到它。
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

SET SVC_NAME=MyServiceName
IF NOT "%~1"=="" SET "SVC_NAME=%~1"

SET SVC_STARTUP=
FOR /F "skip=1" %%s IN ('wmic path Win32_Service where Name^="%SVC_NAME%" get StartMode') DO (
    IF "!SVC_STARTUP!"=="" SET "SVC_STARTUP=%%~s"
)

CALL :"%SVC_STARTUP%" "%SVC_NAME%"
CALL :StopService "%SVC_NAME%"
GOTO :EOF

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:"Boot"
:"System"
:"Auto"
:"Manual"
@ECHO Disabling service '%~1'.
sc.exe config "%~1" start= disabled > NUL
IF NOT ERRORLEVEL 1 @ECHO Service '%~1' disabled.
EXIT /B

:"Disabled"
@ECHO Service '%~1' already disabled.
EXIT /B


::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:StopService
SETLOCAL
SET SVC_STATE=
FOR /F "skip=1" %%s IN ('wmic path Win32_Service where Name^="%~1" get State') DO (
   IF "!SVC_STATE!"=="" SET "SVC_STATE=%%~s"
)
CALL :"%SVC_STATE%" "%~1"
EXIT /B


:"Running"
:"Start Pending"
:"Continue Pending"
:"Pause Pending"
:"Paused"
:"Unknown"
@ECHO Stopping service '%~1'.
sc.exe stop "%~1" > NUL
IF NOT ERRORLEVEL 1 @ECHO Service '%~1' stopped.

EXIT /B

:"Stop Pending"
:"Stopped"
@ECHO Service '%~1' is already stopping/stopped.
EXIT /B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接