如何通过批处理文件检查服务是否正在运行并启动它,如果它没有运行?

发布于 2024-09-11 09:40:31 字数 334 浏览 12 评论 0原文

我想编写一个执行以下操作的批处理文件:

  • 检查服务是否正在运行
    • 如果正在运行,请退出批处理
    • 如果未运行,则启动该服务

到目前为止我用谷歌搜索的代码示例结果证明不起作用,所以我决定不发布它们。

启动服务是通过以下方式完成的:

net start "SERVICENAME"
  1. 如何检查服务是否正在运行,以及如何在批处理文件中创建 if 语句?
  2. 我有点困惑。我必须向网络启动传递什么论据?服务名称还是其显示名称?

I want to write a batch file that performs the following operations:

  • Check if a service is running
    • If is it running, quit the batch
    • If it is not running, start the service

The code samples I googled so far turned out not to be working, so I decided not to post them.

Starting a service is done by:

net start "SERVICENAME"
  1. How can I check if a service is running, and how to make an if statement in a batchfile?
  2. I'm a bit confused. What is the argument I have to pass onto the net start? The service name or its display name?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

纸短情长 2024-09-18 09:40:31

要检查服务的状态,请使用 sc query。对于批处理文件中的 if 块,查看文档

以下代码将检查服务 MyServiceName 的状态,如果未运行则启动它(如果服务未运行则执行 if 块):

for /F "tokens=3 delims=: " %%H in ('sc query "MyServiceName" ^| findstr "        STATE"') do (
  if /I "%%H" NEQ "RUNNING" (
   REM Put your code you want to execute here
   REM For example, the following line
   net start "MyServiceName"
  )
)

作用说明:

  1. 查询属性的服务。
  2. 查找包含文本“STATE”的行
  3. ,对该行进行标记,并提取第三个标记,即包含服务状态的标记。
  4. 针对字符串“RUNNING”测试结果状态

至于您的第二个问题,您想要传递给 net start 的参数是服务名称,而不是显示名称。

To check a service's state, use sc query <SERVICE_NAME>. For if blocks in batch files, check the documentation.

The following code will check the status of the service MyServiceName and start it if it is not running (the if block will be executed if the service is not running):

for /F "tokens=3 delims=: " %%H in ('sc query "MyServiceName" ^| findstr "        STATE"') do (
  if /I "%%H" NEQ "RUNNING" (
   REM Put your code you want to execute here
   REM For example, the following line
   net start "MyServiceName"
  )
)

Explanation of what it does:

  1. Queries the properties of the service.
  2. Looks for the line containing the text "STATE"
  3. Tokenizes that line, and pulls out the 3rd token, which is the one containing the state of the service.
  4. Tests the resulting state against the string "RUNNING"

As for your second question, the argument you will want to pass to net start is the service name, not the display name.

像极了他 2024-09-18 09:40:31

要切换服务,请使用以下命令;

NET START“分布式事务
协调员”||NET STOP”分布式
交易协调员”

To toggle a service use the following;

NET START "Distributed Transaction
Coordinator" ||NET STOP "Distributed
Transaction Coordinator"

轻拂→两袖风尘 2024-09-18 09:40:31

您可以使用以下命令查看服务是否正在运行:

sc query [ServiceName] | findstr /i "STATE"

当我为 NOD32 Antivirus 运行该服务时,我得到:

STATE                       : 4 RUNNING

如果它被停止,我会得到:

STATE                       : 1 STOPPED

您可以在变量中使用它来确定是否使用NET 启动与否。

服务名称应该是服务名称,而不是显示名称。

You can use the following command to see if a service is running or not:

sc query [ServiceName] | findstr /i "STATE"

When I run it for my NOD32 Antivirus, I get:

STATE                       : 4 RUNNING

If it was stopped, I would get:

STATE                       : 1 STOPPED

You can use this in a variable to then determine whether you use NET START or not.

The service name should be the service name, not the display name.

她说她爱他 2024-09-18 09:40:31

应该这样做:

FOR %%a IN (%Svcs%) DO (SC query %%a | FIND /i "RUNNING"
IF ERRORLEVEL 1 SC start %%a)

That should do it:

FOR %%a IN (%Svcs%) DO (SC query %%a | FIND /i "RUNNING"
IF ERRORLEVEL 1 SC start %%a)
Oo萌小芽oO 2024-09-18 09:40:31

独立于语言的版本。

@Echo Off
Set ServiceName=Jenkins


SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(
    echo %ServiceName% not running 
    echo Start %ServiceName%

    Net start "%ServiceName%">nul||(
        Echo "%ServiceName%" wont start 
        exit /b 1
    )
    echo "%ServiceName%" started
    exit /b 0
)||(
    echo "%ServiceName%" working
    exit /b 0
)

Language independent version.

@Echo Off
Set ServiceName=Jenkins


SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(
    echo %ServiceName% not running 
    echo Start %ServiceName%

    Net start "%ServiceName%">nul||(
        Echo "%ServiceName%" wont start 
        exit /b 1
    )
    echo "%ServiceName%" started
    exit /b 0
)||(
    echo "%ServiceName%" working
    exit /b 0
)
萧瑟寒风 2024-09-18 09:40:31

我刚刚找到这个线程,并且想添加到讨论中,如果该人不想使用批处理文件来重新启动服务。在 Windows 中,如果您转到“服务”、“服务属性”,然后转到“恢复”,则会有一个选项。您可以在此处设置服务的参数。喜欢如果服务停止则重新启动服务。此外,您甚至可以让第二次失败尝试执行与重新启动计算机不同的操作。

I just found this thread and wanted to add to the discussion if the person doesn't want to use a batch file to restart services. In Windows there is an option if you go to Services, service properties, then recovery. Here you can set parameters for the service. Like to restart the service if the service stops. Also, you can even have a second fail attempt do something different as in restart the computer.

请远离我 2024-09-18 09:40:31

如果您使用西班牙语的 Windows,请使用西班牙语(使用西班牙语的 Windows 时,代码为):

for /F "tokens=3 delims=: " %%H in ('sc query MYSERVICE ^| findstr "        ESTADO"') do (
  if /I "%%H" NEQ "RUNNING" (
    REM Put your code you want to execute here
    REM For example, the following line
    net start MYSERVICE
  )
)

Reemplazar MYSERVICE con el nombre del servicio que se desea procesar。服务名称为服务属性。 (将 MYSERVICE 替换为要处理的服务的名称。您可以在服务属性中看到服务的名称。)

Cuando se use Windows en Español, el código debe quedar asi (when using Windows in Spanish, code is):

for /F "tokens=3 delims=: " %%H in ('sc query MYSERVICE ^| findstr "        ESTADO"') do (
  if /I "%%H" NEQ "RUNNING" (
    REM Put your code you want to execute here
    REM For example, the following line
    net start MYSERVICE
  )
)

Reemplazar MYSERVICE con el nombre del servicio que se desea procesar. Puedes ver el nombre del servicio viendo las propiedades del servicio. (Replace MYSERVICE with the name of the service to be processed. You can see the name of the service on service properties.)

浪漫人生路 2024-09-18 09:40:31

对于 Windows Server 2012,下面的内容对我有用。仅将“SERVICENAME”替换为实际服务名称:

@ECHO OFF
SET SvcName=SERVICENAME

SC QUERYEX "%SvcName%" | FIND "STATE" | FIND /v "RUNNING" > NUL && (
    ECHO %SvcName% is not running 
    ECHO START %SvcName%

    NET START "%SvcName%" > NUL || (
        ECHO "%SvcName%" wont start 
        EXIT /B 1
    )
    ECHO "%SvcName%" is started
    EXIT /B 0
) || (
    ECHO "%SvcName%" is running
    EXIT /B 0
)

For Windows server 2012 below is what worked for me. Replace only "SERVICENAME" with actual service name:

@ECHO OFF
SET SvcName=SERVICENAME

SC QUERYEX "%SvcName%" | FIND "STATE" | FIND /v "RUNNING" > NUL && (
    ECHO %SvcName% is not running 
    ECHO START %SvcName%

    NET START "%SvcName%" > NUL || (
        ECHO "%SvcName%" wont start 
        EXIT /B 1
    )
    ECHO "%SvcName%" is started
    EXIT /B 0
) || (
    ECHO "%SvcName%" is running
    EXIT /B 0
)
猫烠⑼条掵仅有一顆心 2024-09-18 09:40:31
@echo off

color 1F


@sc query >%COMPUTERNAME%_START.TXT


find /I "AcPrfMgrSvc" %COMPUTERNAME%_START.TXT >nul

IF ERRORLEVEL 0 EXIT

IF ERRORLEVEL 1 NET START "AcPrfMgrSvc"
@echo off

color 1F


@sc query >%COMPUTERNAME%_START.TXT


find /I "AcPrfMgrSvc" %COMPUTERNAME%_START.TXT >nul

IF ERRORLEVEL 0 EXIT

IF ERRORLEVEL 1 NET START "AcPrfMgrSvc"
审判长 2024-09-18 09:40:31

如果服务以这种方式启动,我还希望发送一封电子邮件,因此在 @Ic 代码中添加了一些内容,只是想我会发布它,以防它对任何人有帮助。我使用了 SendMail,但还有其他命令行选项 如何从 Windows 批处理文件发送简单的电子邮件?

set service=MyServiceName

for /F "tokens=3 delims=: " %%H in ('sc query %service% ^| findstr "        STATE"') do (
  if /I "%%H" NEQ "RUNNING" (

    net start %service%

    for /F "tokens=3 delims=: " %%H in ('sc query %service% ^| findstr "        STATE"') do (
      if /I "%%H" EQ "RUNNING" (
        SendMail /smtpserver localhost /to [email protected] /from [email protected] /subject Service Autostart Notification /body Autostart on service %service% succeded.
      ) else (
        SendMail /smtpserver localhost /to [email protected] /from [email protected] /subject Service Autostart Notification /body Autostart on service %service% failed.
      )
    )

  )
)

I also wanted an email sent if the service was started this way so added a bit to @Ic code just thought I would post it in case it helped anyone. I used SendMail but there are other command line options How to send a simple email from a Windows batch file?

set service=MyServiceName

for /F "tokens=3 delims=: " %%H in ('sc query %service% ^| findstr "        STATE"') do (
  if /I "%%H" NEQ "RUNNING" (

    net start %service%

    for /F "tokens=3 delims=: " %%H in ('sc query %service% ^| findstr "        STATE"') do (
      if /I "%%H" EQ "RUNNING" (
        SendMail /smtpserver localhost /to [email protected] /from [email protected] /subject Service Autostart Notification /body Autostart on service %service% succeded.
      ) else (
        SendMail /smtpserver localhost /to [email protected] /from [email protected] /subject Service Autostart Notification /body Autostart on service %service% failed.
      )
    )

  )
)
焚却相思 2024-09-18 09:40:31

使用 Powershell 脚本启动服务。您可以将其链接到任务计划程序并定期或根据需要触发它。
将其创建为 PS1 文件,即扩展名为 PS1 的文件,然后让该文件从任务计划程序触发。

要在任务计划程序中启动停止服务

(如果您在服务器上使用它),请在参数中使用

-noprofile -executionpolicybypass -file "C:\Service Restart Scripts\StopService.PS1"

通过在 cmd 上运行相同的命令来验证它是否有效也在任务计划程序上

$Password = "Enter_Your_Password"
$UserAccount = "Enter_Your_AccountInfor"
$MachineName = "Enter_Your_Machine_Name"
$ServiceList = @("test.SocketService","test.WcfServices","testDesktopService","testService")
$PasswordSecure = $Password | ConvertTo-SecureString -AsPlainText -Force
$Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $UserAccount, $PasswordSecure 

$LogStartTime = Get-Date -Format "MM-dd-yyyy hh:mm:ss tt"
$FileDateTimeStamp = Get-Date -Format "MM-dd-yyyy_hh"
$LogFileName = "C:\Users\krakhil\Desktop\Powershell\Logs\StartService_$FileDateTimeStamp.txt" 


#code to start the service

"`n####################################################################" > $LogFileName
"####################################################################" >> $LogFileName
"######################  STARTING SERVICE  ##########################" >> $LogFileName

for($i=0;$i -le 3; $i++)
{
"`n`n" >> $LogFileName
$ServiceName = $ServiceList[$i]
"$LogStartTime => Service Name: $ServiceName" >> $LogFileName

Write-Output "`n####################################"
Write-Output "Starting Service - " $ServiceList[$i]

"$LogStartTime => Starting Service: $ServiceName" >> $LogFileName
Start-Service $ServiceList[$i]

$ServiceState = Get-Service | Where-Object {$_.Name -eq $ServiceList[$i]}

if($ServiceState.Status -eq "Running")
{
"$LogStartTime => Started Service Successfully: $ServiceName" >> $LogFileName
Write-Host "`n Service " $ServiceList[$i] " Started Successfully"
}
else
{
"$LogStartTime => Unable to Stop Service: $ServiceName" >> $LogFileName
Write-Output "`n Service didn't Start. Current State is - "
Write-Host $ServiceState.Status
}
}

#code to stop the service

"`n####################################################################" > $LogFileName
"####################################################################" >> $LogFileName
"######################  STOPPING SERVICE  ##########################" >> $LogFileName

for($i=0;$i -le 3; $i++)
{
"`n`n" >> $LogFileName
$ServiceName = $ServiceList[$i]
"$LogStartTime => Service Name: $ServiceName" >> $LogFileName

Write-Output "`n####################################"
Write-Output "Stopping Service - " $ServiceList[$i]

"$LogStartTime => Stopping Service: $ServiceName" >> $LogFileName
Stop-Service $ServiceList[$i]

$ServiceState = Get-Service | Where-Object {$_.Name -eq $ServiceList[$i]}

if($ServiceState.Status -eq "Stopped")
{
"$LogStartTime => Stopped Service Successfully: $ServiceName" >> $LogFileName
Write-Host "`n Service " $ServiceList[$i] " Stopped Successfully"
}
else
{
"$LogStartTime => Unable to Stop Service: $ServiceName" >> $LogFileName
Write-Output "`nService didn't Stop. Current State is - "
Write-Host $ServiceState.Status
}
}

Starting Service using Powershell script. You can link this to task scheduler and trigger it at intervals or as needed.
Create this as a PS1 file i.e. file with extension PS1 and then let this file be triggered from task scheduler.

To start stop service

in task scheduler if you are using it on server use this in arguments

-noprofile -executionpolicy bypass -file "C:\Service Restart Scripts\StopService.PS1"

verify by running the same on cmd if it works it should work on task scheduler also

$Password = "Enter_Your_Password"
$UserAccount = "Enter_Your_AccountInfor"
$MachineName = "Enter_Your_Machine_Name"
$ServiceList = @("test.SocketService","test.WcfServices","testDesktopService","testService")
$PasswordSecure = $Password | ConvertTo-SecureString -AsPlainText -Force
$Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $UserAccount, $PasswordSecure 

$LogStartTime = Get-Date -Format "MM-dd-yyyy hh:mm:ss tt"
$FileDateTimeStamp = Get-Date -Format "MM-dd-yyyy_hh"
$LogFileName = "C:\Users\krakhil\Desktop\Powershell\Logs\StartService_$FileDateTimeStamp.txt" 


#code to start the service

"`n####################################################################" > $LogFileName
"####################################################################" >> $LogFileName
"######################  STARTING SERVICE  ##########################" >> $LogFileName

for($i=0;$i -le 3; $i++)
{
"`n`n" >> $LogFileName
$ServiceName = $ServiceList[$i]
"$LogStartTime => Service Name: $ServiceName" >> $LogFileName

Write-Output "`n####################################"
Write-Output "Starting Service - " $ServiceList[$i]

"$LogStartTime => Starting Service: $ServiceName" >> $LogFileName
Start-Service $ServiceList[$i]

$ServiceState = Get-Service | Where-Object {$_.Name -eq $ServiceList[$i]}

if($ServiceState.Status -eq "Running")
{
"$LogStartTime => Started Service Successfully: $ServiceName" >> $LogFileName
Write-Host "`n Service " $ServiceList[$i] " Started Successfully"
}
else
{
"$LogStartTime => Unable to Stop Service: $ServiceName" >> $LogFileName
Write-Output "`n Service didn't Start. Current State is - "
Write-Host $ServiceState.Status
}
}

#code to stop the service

"`n####################################################################" > $LogFileName
"####################################################################" >> $LogFileName
"######################  STOPPING SERVICE  ##########################" >> $LogFileName

for($i=0;$i -le 3; $i++)
{
"`n`n" >> $LogFileName
$ServiceName = $ServiceList[$i]
"$LogStartTime => Service Name: $ServiceName" >> $LogFileName

Write-Output "`n####################################"
Write-Output "Stopping Service - " $ServiceList[$i]

"$LogStartTime => Stopping Service: $ServiceName" >> $LogFileName
Stop-Service $ServiceList[$i]

$ServiceState = Get-Service | Where-Object {$_.Name -eq $ServiceList[$i]}

if($ServiceState.Status -eq "Stopped")
{
"$LogStartTime => Stopped Service Successfully: $ServiceName" >> $LogFileName
Write-Host "`n Service " $ServiceList[$i] " Stopped Successfully"
}
else
{
"$LogStartTime => Unable to Stop Service: $ServiceName" >> $LogFileName
Write-Output "`nService didn't Stop. Current State is - "
Write-Host $ServiceState.Status
}
}
三月梨花 2024-09-18 09:40:31

与 @DanielSerrano 的答案相关,我最近对 ​​sc.exe 命令的本地化(即西班牙语)感到有点困惑。我的建议是查明保存数字服务状态的行和令牌并对其进行解释,这应该更加可靠:

@echo off

rem TODO: change to the desired service name
set TARGET_SERVICE=w32time

set SERVICE_STATE=
rem Surgically target third line, as some locales (such as Spanish) translated the utility's output
for /F "skip=3 tokens=3" %%i in ('""%windir%\system32\sc.exe" query "%TARGET_SERVICE%" 2>nul"') do (
  if not defined SERVICE_STATE set SERVICE_STATE=%%i
)
rem Process result
if not defined SERVICE_STATE (
  echo ERROR: could not obtain service state!
) else (
  rem NOTE: values correspond to "SERVICE_STATUS.dwCurrentState"
  rem https://msdn.microsoft.com/en-us/library/windows/desktop/ms685996(v=vs.85).aspx
  if not %SERVICE_STATE%==4 (
    echo WARNING: service is not running
    rem TODO: perform desired operation
    rem net start "%TARGET_SERVICE%"
  ) else (
    echo INFORMATION: service is running
  )
)

测试环境:

  • Windows XP(32 位)英语
  • Windows 10(32 位)西班牙语
  • Windows 10(64 位 ) -位) 英语

Related with the answer by @DanielSerrano, I've been recently bit by localization of the sc.exe command, namely in Spanish. My proposal is to pin-point the line and token which holds numerical service state and interpret it, which should be much more robust:

@echo off

rem TODO: change to the desired service name
set TARGET_SERVICE=w32time

set SERVICE_STATE=
rem Surgically target third line, as some locales (such as Spanish) translated the utility's output
for /F "skip=3 tokens=3" %%i in ('""%windir%\system32\sc.exe" query "%TARGET_SERVICE%" 2>nul"') do (
  if not defined SERVICE_STATE set SERVICE_STATE=%%i
)
rem Process result
if not defined SERVICE_STATE (
  echo ERROR: could not obtain service state!
) else (
  rem NOTE: values correspond to "SERVICE_STATUS.dwCurrentState"
  rem https://msdn.microsoft.com/en-us/library/windows/desktop/ms685996(v=vs.85).aspx
  if not %SERVICE_STATE%==4 (
    echo WARNING: service is not running
    rem TODO: perform desired operation
    rem net start "%TARGET_SERVICE%"
  ) else (
    echo INFORMATION: service is running
  )
)

Tested with:

  • Windows XP (32-bit) English
  • Windows 10 (32-bit) Spanish
  • Windows 10 (64-bit) English
牛↙奶布丁 2024-09-18 09:40:31
@Echo off

Set ServiceName=wampapache64

SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(

echo %ServiceName% not running
echo  

Net start "%ServiceName%"


    SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(
        Echo "%ServiceName%" wont start
    )
        echo "%ServiceName%" started

)||(
    echo "%ServiceName%" was working and stopping
    echo  

    Net stop "%ServiceName%"

)


pause
@Echo off

Set ServiceName=wampapache64

SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(

echo %ServiceName% not running
echo  

Net start "%ServiceName%"


    SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(
        Echo "%ServiceName%" wont start
    )
        echo "%ServiceName%" started

)||(
    echo "%ServiceName%" was working and stopping
    echo  

    Net stop "%ServiceName%"

)


pause
白昼 2024-09-18 09:40:31

也许有更简单的方法?只需添加到此处的答案列表:

@for /f "tokens=1,* delims=: " %%a in ('sc queryex state=Inactive') do net start "%%b"

Maybe a much simpler way? Just adding to the list of answers here:

@for /f "tokens=1,* delims=: " %%a in ('sc queryex state=Inactive') do net start "%%b"
小镇女孩 2024-09-18 09:40:31

如果您使用nssm,请使用以下命令

nssm status MyServiceName

< strong>如果服务正在运行,则输出

SERVICE_RUNNING

如果服务未运行,则输出

SERVICE_STOPPED

If you are using nssm then use the following command

nssm status MyServiceName

Output if service is running

SERVICE_RUNNING

Output if service is not running

SERVICE_STOPPED
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文