停止/启动远程Windows服务并等待其打开/closures

这个问题的最佳答案告诉我如何停止/启动远程服务。 大。 现在,我需要的是等待实际的停止/开始完成。 所以,我正在寻找的是一个dos命令来:

  1. 启动一个服务,只有在服务启动后(或超时后,提高错误级别)
  2. 停止服务,仅在服务停止后返回

我创build了一组使用sc.exe来执行此操作的批处理脚本。 他们附在下面。 要运行这些脚本, 您应该是在目标计算机上拥有pipe理权限的用户,并从属于同一个域成员的计算机上运行 。 可以将其设置为能够从域外运行(例如从VPN),但是通过涉及防火墙,DCOM和安全证书,还有很多安全层。

其中一天,我要弄清楚PowerShell的等价物,这应该更容易。

safeServiceStart.bat

@echo off :: This script originally authored by Eric Falsken IF [%1]==[] GOTO usage IF [%2]==[] GOTO usage ping -n 1 %1 | FIND "TTL=" >NUL IF errorlevel 1 GOTO SystemOffline SC \\%1 query %2 | FIND "STATE" >NUL IF errorlevel 1 GOTO SystemOffline :ResolveInitialState SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StartService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StartedService SC \\%1 query %2 | FIND "STATE" | FIND "PAUSED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline echo Service State is changing, waiting for service to resolve its state before making changes sc \\%1 query %2 | Find "STATE" timeout /t 2 /nobreak >NUL GOTO ResolveInitialState :StartService echo Starting %2 on \\%1 sc \\%1 start %2 >NUL GOTO StartingService :StartingServiceDelay echo Waiting for %2 to start timeout /t 2 /nobreak >NUL :StartingService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 1 GOTO StartingServiceDelay :StartedService echo %2 on \\%1 is started GOTO:eof :SystemOffline echo Server \\%1 is not accessible or is offline GOTO:eof :usage echo %0 [system name] [service name] echo Example: %0 server1 MyService echo. GOTO:eof 

safeServiceStop.bat

 @echo off :: This script originally authored by Eric Falsken IF [%1]==[] GOTO usage IF [%2]==[] GOTO usage ping -n 1 %1 | FIND "TTL=" >NUL IF errorlevel 1 GOTO SystemOffline SC \\%1 query %2 | FIND "STATE" >NUL IF errorlevel 1 GOTO SystemOffline :ResolveInitialState SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StopService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StopedService SC \\%1 query %2 | FIND "STATE" | FIND "PAUSED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline echo Service State is changing, waiting for service to resolve its state before making changes sc \\%1 query %2 | Find "STATE" timeout /t 2 /nobreak >NUL GOTO ResolveInitialState :StopService echo Stopping %2 on \\%1 sc \\%1 stop %2 %3 >NUL GOTO StopingService :StopingServiceDelay echo Waiting for %2 to stop timeout /t 2 /nobreak >NUL :StopingService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 1 GOTO StopingServiceDelay :StopedService echo %2 on \\%1 is stopped GOTO:eof :SystemOffline echo Server \\%1 or service %2 is not accessible or is offline GOTO:eof :usage echo Will cause a remote service to STOP (if not already stopped). echo This script will waiting for the service to enter the stopped state if necessary. echo. echo %0 [system name] [service name] {reason} echo Example: %0 server1 MyService echo. echo For reason codes, run "sc stop" GOTO:eof 

safeServiceRestart.bat

 @echo off :: This script originally authored by Eric Falsken if [%1]==[] GOTO usage if [%2]==[] GOTO usage ping -n 1 %1 | FIND "TTL=" >NUL IF errorlevel 1 GOTO SystemOffline SC \\%1 query %2 | FIND "STATE" >NUL IF errorlevel 1 GOTO SystemOffline :ResolveInitialState SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StopService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO StartService SC \\%1 query %2 | FIND "STATE" | FIND "PAUSED" >NUL IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline echo Service State is changing, waiting for service to resolve its state before making changes sc \\%1 query %2 | Find "STATE" timeout /t 2 /nobreak >NUL GOTO ResolveInitialState :StopService echo Stopping %2 on \\%1 sc \\%1 stop %2 %3 >NUL GOTO StopingService :StopingServiceDelay echo Waiting for %2 to stop timeout /t 2 /nobreak >NUL :StopingService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >NUL IF errorlevel 1 GOTO StopingServiceDelay :StopedService echo %2 on \\%1 is stopped GOTO StartService :StartService echo Starting %2 on \\%1 sc \\%1 start %2 >NUL GOTO StartingService :StartingServiceDelay echo Waiting for %2 to start timeout /t 2 /nobreak >NUL :StartingService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >NUL IF errorlevel 1 GOTO StartingServiceDelay :StartedService echo %2 on \\%1 is started GOTO:eof :SystemOffline echo Server \\%1 or service %2 is not accessible or is offline GOTO:eof :usage echo Will restart a remote service, waiting for the service to stop/start (if necessary) echo. echo %0 [system name] [service name] {reason} echo Example: %0 server1 MyService echo. echo For reason codes, run "sc stop" GOTO:eof 

那么powershell和WaitForStatus呢? 例如,下面的脚本将在远程计算机上重新启动SQL Server:

 $computer = "COMPUTER_NAME" $me = new-object -typename System.Management.Automation.PSCredential -argumentlist "DOMAIN\user", (convertto-securestring "password" -asplaintext -force) $restartSqlServer = { $sqlServer = get-service mssqlserver $waitInterval = new-timespan -seconds 5 if (-not ($sqlServer.Status -eq "Stopped")) { $sqlServer.Stop() $sqlServer.WaitForStatus('Stopped', $waitInterval) } $sqlServer.Start() $sqlServer.WaitForStatus('Running', $waitInterval) } icm -ComputerName $computer -ScriptBlock $restartSqlServer -Credential $me 

我从来没有见过这样做的具体做法,但用C \ C#\ VB或任何其他可以轻松访问Service API的语言来敲出这样的实用程序是相当容易的。 以下是C#中的一些示例。

 using System; using System.ComponentModel; using System.ServiceProcess; namespace SCSync { class Program { private const int ERROR_SUCCESS = 0; private const int ERROR_INVALID_COMMAND_LINE = 1; private const int ERROR_NO_ACCESS = 2; private const int ERROR_COMMAND_TIMEOUT = 3; private const int ERROR_NO_SERVICE = 4; private const int ERROR_NO_SERVER = 5; private const int ERROR_INVALID_STATE = 6; private const int ERROR_UNSPECIFIED = 7; static int Main(string[] args) { if (args.Length < 2 || args.Length > 4) { ShowUsage(); return ERROR_INVALID_COMMAND_LINE; } string serviceName = args[0]; string command = args[1].ToUpper(); string serverName = "."; string timeoutString = "30"; int timeout; if (args.Length > 2) { if (args[2].StartsWith(@"\\")) { serverName = args[2].Substring(2); if (args.Length > 3) { timeoutString = args[3]; } } else { timeoutString = args[2]; } } if (!int.TryParse(timeoutString, out timeout)) { Console.WriteLine("Invalid timeout value.\n"); ShowUsage(); return ERROR_INVALID_COMMAND_LINE; } try { ServiceController sc = new ServiceController(serviceName, serverName); switch (command) { case "START": sc.Start(); sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 0, timeout)); break; case "STOP": sc.Stop(); sc.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 0, timeout)); break; case "PAUSE": sc.Pause(); sc.WaitForStatus(ServiceControllerStatus.Paused, new TimeSpan(0, 0, 0, timeout)); break; case "CONTINUE": sc.Continue(); sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 0, timeout)); break; default: Console.WriteLine("Invalid command value.\n"); ShowUsage(); return ERROR_INVALID_COMMAND_LINE; } } catch (System.ServiceProcess.TimeoutException) { Console.WriteLine("Operation timed out.\n"); return ERROR_COMMAND_TIMEOUT; } catch (UnauthorizedAccessException) { Console.WriteLine("You are not authorized to perform this action.\n"); return ERROR_NO_ACCESS; } catch (InvalidOperationException opEx) { Win32Exception winEx = opEx.InnerException as Win32Exception; if (winEx != null) { switch (winEx.NativeErrorCode) { case 5: //ERROR_ACCESS_DENIED Console.WriteLine("You are not authorized to perform this action.\n"); return ERROR_NO_ACCESS; case 1722: //RPC_S_SERVER_UNAVAILABLE Console.WriteLine("The server is unavailable or does not exist.\n"); return ERROR_NO_SERVER; case 1060: //ERROR_SERVICE_DOES_NOT_EXIST Console.WriteLine("The service does not exist.\n"); return ERROR_NO_SERVICE; case 1056: //ERROR_SERVICE_ALREADY_RUNNING Console.WriteLine("The service is already running.\n"); return ERROR_INVALID_STATE; case 1062: //ERROR_SERVICE_NOT_ACTIVE Console.WriteLine("The service is not running.\n"); return ERROR_INVALID_STATE; default: break; } } Console.WriteLine(opEx.ToString()); return ERROR_UNSPECIFIED; } catch (Exception ex) { Console.WriteLine(ex.ToString()); return ERROR_UNSPECIFIED; } return ERROR_SUCCESS; } private static void ShowUsage() { Console.WriteLine("SCSync usage:\n"); Console.WriteLine("SCSync.exe service command <server> <timeout>\n"); Console.WriteLine(" service The name of the service upon which the command will act. (Required)"); Console.WriteLine(" command The command to execute - one of: start|stop|pause|continue. (Required)"); Console.WriteLine(" server The name of the server on which the target service runs. This must start with \\. (Optional)"); Console.WriteLine(" timeout The timeout period in seconds in which the command should finish. The default is 30 seconds. (Optional)"); Console.WriteLine("\n"); } } } 

WaitForStatus只是一个轮询循环,可以用任何其他语言轻松replace。 剩下的只是OpenService和ControlService。

Eric Falsken的解决scheme非常完美。 +1。

但我想补充说,超时命令有时会失败,错误:“不支持inputredirect,立即退出进程”

要解决这个问题,我不得不更换超时命令:

 timeout /t 2 /nobreak >NUL 

具体如下:

 ping -n 2 127.0.0.1 1>NUL 

在10/20/2011编辑 – 更新我的代码。 我完全debugging之前发布了它。 非常感谢Eric Falsken。 多么好的解决scheme 我调整了埃里克的代码(顺便说一下,如果你打算使用它的话,可以找几个印刷错误)。 我添加了日志和一些额外的错误检查埃里克没有考虑的一些条件。 由于我对服务重启(而不仅仅是停止和/或启动)最感兴趣,所以我只build立在Eric的重启代码上。 无论如何,我张贴我的版本,希望你喜欢它!

 @ECHO off :: This script originally authored by Eric Falsken http://stackoverflow.com/ :: Revised for by George Perkins 10/20/2011 IF [%1]==[] GOTO Usage IF [%2]==[] GOTO Usage :SetLocalVariables SET /A MyDelay=0 SET MyHours=%time:~0,2% IF %MyHours%==0 SET MyHours=00 IF %MyHours%==1 SET MyHours=01 IF %MyHours%==2 SET MyHours=02 IF %MyHours%==3 SET MyHours=03 IF %MyHours%==4 SET MyHours=04 IF %MyHours%==5 SET MyHours=05 IF %MyHours%==6 SET MyHours=06 IF %MyHours%==7 SET MyHours=07 IF %MyHours%==8 SET MyHours=08 IF %MyHours%==9 SET MyHours=09 SET MyMinutes=%time:~3,2% SET MySeconds=%time:~6,2% SET MyHundredths=%time:~9,2% SET MyMonth=%date:~4,2% SET MyDay=%date:~-7,2% SET MyCentury=%date:~-4,4% SET MyTimeStamp=%MyCentury%%MyMonth%%MyDay%%MyHours%%MyMinutes%%MySeconds% IF "%3" == "" ( SET MyLog=C:\Temp ) ELSE ( SET MyLog=%3 ) SET MyLogFile=%MyLog%\ServiceRestart%MyTimeStamp%.log ECHO. ECHO. >> %MyLogFile% ECHO ------------- ------------- %MyHours%:%MyMinutes%:%MySeconds%.%MyHundredths% %MyMonth%/%MyDay%/%MyCentury% ------------- ------------- ECHO ------------- ------------- %MyHours%:%MyMinutes%:%MySeconds%.%MyHundredths% %MyMonth%/%MyDay%/%MyCentury% ------------- ------------- >> %MyLogFile% ECHO Begin batch program %0. ECHO Begin batch program %0. >> %MyLogFile% ECHO Logging to file %MyLogFile%. ECHO Logging to file %MyLogFile%. >> %MyLogFile% ECHO Attempting to restart service %2 on computer %1. ECHO Attempting to restart service %2 on computer %1. >> %MyLogFile% PING -n 1 %1 | FIND "TTL=" >> %MyLogFile% IF errorlevel 1 IF NOT errorlevel 2 GOTO SystemOffline SC \\%1 query %2 | FIND "FAILED 1060" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO InvalidServiceName SC \\%1 query %2 | FIND "STATE" >> %MyLogFile% IF errorlevel 1 IF NOT errorlevel 2 GOTO SystemOffline :ResolveInitialState SET /A MyDelay+=1 SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO StopService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO StartService SC \\%1 query %2 | FIND "STATE" | FIND "PAUSED" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline ECHO Service State is changing, waiting %MyDelay% seconds for service to resolve its state before making changes. ECHO Service State is changing, waiting %MyDelay% seconds for service to resolve its state before making changes. >> %MyLogFile% TIMEOUT /t %MyDelay% /nobreak >> %MyLogFile% GOTO ResolveInitialState :StopService SET /A MyDelay=0 ECHO Stopping %2 on \\%1. ECHO Stopping %2 on \\%1. >> %MyLogFile% SC \\%1 stop %2 | FIND "FAILED" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO Unstoppable :StoppingServiceDelay SET /A MyDelay+=1 IF %MyDelay%==21 GOTO MaybeUnStoppable ECHO Waiting %MyDelay% seconds for %2 to stop. ECHO Waiting %MyDelay% seconds for %2 to stop. >> %MyLogFile% TIMEOUT /t %MyDelay% /nobreak >> %MyLogFile% :StoppingService SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO StoppedService SC \\%1 query %2 | FIND "STATE" | FIND "STOP_PENDING" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO StoppingServiceDelay GOTO StoppingServiceDelay :MaybeUnStoppable :: If we got here we waited approximately 3 mintues and the service has not stopped. SC \\%1 query %2 | FIND "NOT_STOPPABLE" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO OneLastChance GOTO Unstoppable :OneLastChance SC \\%1 stop %2 >> %MyLogFile% SET /A MyDelay+=1 ECHO Waiting %MyDelay% seconds for %2 to stop. ECHO Waiting %MyDelay% seconds for %2 to stop. >> %MyLogFile% TIMEOUT /t %MyDelay% /nobreak >> %MyLogFile% SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO StoppedService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >> %MyLogFile% IF errorlevel 1 IF NOT errorlevel 2 GOTO UnknownState SC \\%1 query %2 | FIND "NOT_STOPPABLE" >> %MyLogFile% IF errorlevel 0 IF NOT errorlevel 1 GOTO Unstoppable GOTO StoppingServiceDelay :StoppedService ECHO %2 on \\%1 is stopped. ECHO %2 on \\%1 is stopped. >> %MyLogFile% GOTO StartService :StartService SET /A MyDelay=0 ECHO Starting %2 on \\%1. ECHO Starting %2 on \\%1. >> %MyLogFile% SC \\%1 start %2 >> %MyLogFile% GOTO StartingService :StartingServiceDelay SET /A MyDelay+=1 ECHO Waiting %MyDelay% seconds for %2 to start. ECHO Waiting %MyDelay% seconds for %2 to start. >> %MyLogFile% TIMEOUT /t %MyDelay% /nobreak >> %MyLogFile% :StartingService SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >> %MyLogFile% IF errorlevel 1 IF NOT errorlevel 2 GOTO StartingServiceDelay :StartedService ECHO %2 on \\%1 is started. ECHO %2 on \\%1 is started. >> %MyLogFile% GOTO EndExit :SystemOffline ECHO Failure! Server \\%1 or service %2 is not accessible or is offline! ECHO Failure! Server \\%1 or service %2 is not accessible or is offline! >> %MyLogFile% ECHO See log file %MyLogFile% for details! GOTO EndExit :InvalidServiceName ECHO Failure! Service %2 is not valid! ECHO Failure! Service %2 is not valid! >> %MyLogFile% ECHO See log file %MyLogFile% for details! GOTO EndExit :UnknownState ECHO Failure! Service %2 in an unknown state and cannot be stopped! ECHO Failure! Service %2 in an unknown state and cannot be stopped! >> %MyLogFile% ECHO See log file %MyLogFile% for details! GOTO EndExit :UnStoppable ECHO Failure! Service %2 cannot be stopped! Check dependencies or system state. ECHO Failure! Service %2 cannot be stopped! Check dependencies or system state. >> %MyLogFile% ECHO See log file %MyLogFile% for details! GOTO EndExit :Usage ECHO Will restart a remote service, waiting for the service to stop/start (if necessary). ECHO. ECHO Usage: ECHO %0 [system name] [service name] [logfile path] ECHO Example: %0 server1 MyService C:\Temp\Log ECHO. GOTO EndExit :EndExit ECHO. ECHO %0 Ended. ECHO. 

那么PowerShell和Restart-Service commandlet呢? 🙂

 Get-Service W3SVC -computer myserver | Restart-Service 

埃里克·法尔斯肯(Eric Falsken)的剧本对于这个目的来说太棒 但是请注意,他们使用超时命令,它只在Vista / Server2003及更新版本中可用。 对于XP机器,您可以使用NT资源工具包中的sleep.exe。 (这应该是埃里克的回答,但没有足够的代表这样做)。

我改进了Eric Falsken的剧本,并由Gerorge Perkins修改。

变化:

  • 现在它不仅是一个重启脚本。 该脚本可以启动,停止并重新启动本地或远程服务;
  • 删除日志(如果你想这样做,你可以简单地通过启动SCRIPT_NAME.bat> logfile.txt)来使用它;
  • 稀疏的优化。

      @ECHOclosures
     ::此脚本最初由Eric Falsken撰写http://stackoverflow.com/
     ::由George Perkins 10/20/2011修订
     ::由Armando Contestabile 02/23/2015修改
     IF“%1”==“”GOTO用法
     IF“%2”==“”GOTO用法
    
     SET ACTION =%1
     SET SERVICENAME =%2
    
     IF“%3”==“”(
         SET SYSTEMNAME =%COMPUTERNAME%
     )ELSE(
         SET SYSTEMNAME =%3
     )
    
     IF“%ACTION%”==“停止”(
         SET ACTION = STOP
     )否则如果“%ACTION%”==“停止”(
         SET ACTION = STOP
     )否则如果“%ACTION%”==“开始”(
         SET ACTION = START
     )否则如果“%ACTION%”==“START”(
         SET ACTION = START
     )否则如果“%ACTION%”==“重启”(
         SET ACTION = RESTART
     )否则如果“%ACTION%”==“RESTART”(
         SET ACTION = RESTART
     )ELSE GOTO用法
    
     SET STATE =
     SET CURRENT_STATUS =
     SET / A DEFAULT_DELAY = 5
     SET / A SLEEP_COUNT = 0
     SET / A RESTARTED = 0
     SET / A MAX_WAIT_PERIODS = 5
    
    回声。
     ECHO尝试在计算机%SYSTEMNAME%上执行%ACTION%服务%SERVICENAME%。
    
     PING -n 1%SYSTEMNAME%| find“TTL =”> nul 2>&1
     IF ERRORLEVEL 1 IF NOT ERRORLEVEL 2(
         ECHO失败! 服务器\\%SYSTEMNAME%或服务%SERVICENAME%不可访问或脱机!
         EXIT / B 1
     )
     SC \\%SYSTEMNAME%查询%SERVICENAME%| find“失败1060”> nul 2>&1
     IF ERRORLEVEL 0 IF NOT ERRORLEVEL 1(
         ECHO失败! 服务%SERVICENAME%无效!
         EXIT / B 2
     )
     SC \\%SYSTEMNAME%查询%SERVICENAME%| find“状态”> nul 2>&1
     IF ERRORLEVEL 1 IF NOT ERRORLEVEL 2(
         ECHO失败! 服务器\\%SYSTEMNAME%或服务%SERVICENAME%不可访问或脱机!
         EXIT / B 3
     )
    
     :调度
     FOR / f“tokens = *”%% i IN('SC \\%SYSTEMNAME%query%SERVICENAME%^ | FIND“STATE”')DO SET STATE = %% i
    
     ECHO%STATE%|  FINDSTR / C:“1”> nul
     IF%ERRORLEVEL%== 0 SET CURRENT_STATUS = STOPPED
     ECHO%STATE%|  FINDSTR / C:“2”> nul
     IF%ERRORLEVEL%== 0 SET CURRENT_STATUS = START_PENDING
     ECHO%STATE%|  FINDSTR / C:“3”> nul
     IF%ERRORLEVEL%== 0 SET CURRENT_STATUS = STOP_PENDING
     ECHO%STATE%|  FINDSTR / C:“4”> nul
     IF%ERRORLEVEL%== 0 SET CURRENT_STATUS = RUNNING
     ECHO%STATE%|  FINDSTR / C:“5”> nul
     IF%ERRORLEVEL%== 0 SET CURRENT_STATUS = CONTINUE_PENDING
     ECHO%STATE%|  FINDSTR / C:“6”> nul
     IF%ERRORLEVEL%== 0 SET CURRENT_STATUS = PAUSE_PENDING
     ECHO%STATE%|  FINDSTR / C:“7”> nul
     IF%ERRORLEVEL%== 0 SET CURRENT_STATUS = PAUSED
    
     ECHO当前的服务状态是%CURRENT_STATUS%
    
     IF NOT“%CURRENT_STATUS%”==“RUNNING”如果不是“%CURRENT_STATUS%”==“STOPPED”IF NOT“%CURRENT_STATUS%”==“PAUSED”(
         IF“%SLEEP_COUNT%”==“%MAX_WAIT_PERIODS%”(
             ECHO服务状态不会改变。 脚本执行被取消。
             EXIT / B 4
         )
         ECHO服务状态正在改变,正在等待%DEFAULT_DELAY%秒...
         SLEEP%DEFAULT_DELAY%
         SET / A SLEEP_COUNT + = 1
         GOTO调度
     )
    
     IF“%ACTION%”==“START”(
         IF“%CURRENT_STATUS%”==“正在运行”(
             ECHO服务%SERVICENAME%正在运行。
             GOTO EndExit
         )ELSE(
             GOTO StartService
         )
     )否则如果“%ACTION%”==“RESTART”(
         IF“%CURRENT_STATUS%”==“正在运行”(
             IF%RESTARTED%== 1(
                 ECHO服务%SERVICENAME%重新启动。
                 GOTO EndExit
             )
             SET / A SLEEP_COUNT = 0
             GOTO StopService
         )ELSE(
             SET / A RESTARTED = 1
             GOTO StartService
         )
     )否则如果“%ACTION%”==“停止”(
         IF“%CURRENT_STATUS%”==“STOPPED”(
             ECHO服务%SERVICENAME%已停止。
             GOTO EndExit
         )ELSE(
             GOTO StopService
         )
     )
    
     :StartService
     ECHO在\\%SYSTEMNAME%上启动%SERVICENAME%
     SC \\%SYSTEMNAME%start%SERVICENAME%> nul 2>&1
     SET SLEEP_COUNT = 0
     GOTO调度
    
     :StopService
     ECHO在\\%SYSTEMNAME%上停止%SERVICENAME%
     SC \\%SYSTEMNAME%stop%SERVICENAME%> nul 2>&1
     SET SLEEP_COUNT = 0
     GOTO调度
    
     :用法
     ECHO该脚本可以启动/停止/重新启动本地或远程服务,等待服务停止/启动^(如有必要^)。
    回声。
     ECHO用法:
     ECHO%0 ^ <start ^ | stop ^ | restart ^> ^ <SERVICE ^> [SYSTEM]
    回声。
     ECHO如果没有提供SYSTEM,脚本将尝试在本地系统上执行。
     EXIT / B 5
    
     :EndExit
    回声。
     EXIT / B 0
    

NET START和NET STOP应该不会返回,直到服务指示服务已经成功启动或停止。

我不相信你可以用一个简单的dos命令来做到这一点。 您可能会检查代码项目或其他类似的网站,看看是否有一个自定义的解决scheme已经。

如果没有,您可以编写一个辅助的Windows服务,通过WCF端点公开启动/停止function来为您做这个工作。 要远程访问此辅助服务,您可以编写一个连接到此服务的简单控制台应用程序,以启动/停止有问题的Windows服务。 由于它是一个控制台应用程序,它会模仿从命令行工作的期望的行为,直到完成(或发生错误)才返回。 这不是你想要的简单而简单的解决scheme,但是我会把它放在那里考虑。