remota - no aparece escritorio remoto windows 8
Detener/iniciar un servicio remoto de Windows y esperar que se abra/se cierre (10)
¿Qué pasa con el comando PowerShell y Restart-Service ? :)
Get-Service W3SVC -computer myserver | Restart-Service
La respuesta principal a esta pregunta me dice cómo detener / iniciar un servicio remoto. Estupendo. Ahora, todo lo que necesito es esperar a que se complete el paro / inicio real. Entonces, lo que estoy buscando es un comando dos para:
- Inicie un servicio, debe devolver solo después de que se haya iniciado el servicio (o después de un tiempo de espera, aumento del nivel de error)
- Detener un servicio, devolver solo después de que se detenga el servicio
¿Qué pasa con powershell y WaitForStatus? Por ejemplo, el siguiente script reiniciaría SQL Server en una máquina remota:
$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
Creé un conjunto de scripts por lotes que usan sc.exe para hacer esto. Ellos están adjuntos a continuación. Para ejecutar estos scripts, debe ser un usuario con derechos de administración en el equipo de destino y ejecutarlo desde una computadora que sea miembro del mismo dominio . Es posible configurarlo para que pueda ejecutarse desde fuera del dominio (como desde una VPN), pero hay muchas capas de seguridad para trabajar mediante el uso de firewalls, DCOM y credenciales de seguridad.
Uno de estos días, voy a averiguar el equivalente de PowerShell, que debería ser mucho más fácil.
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
Editar el 20/10/2011 - actualicé mi código. Lo publiqué antes de la depuración completa. Muchas gracias a Eric Falsken. Qué gran solución. Ajusté el código de Eric (por cierto, busque un par de errores tipográficos si tiene la intención de usarlo). Agregué el registro y algunas verificaciones de errores adicionales para algunas condiciones que Eric no dio cuenta. Como estoy más interesado en un reinicio del servicio (no solo para detener o iniciar), solo me basé en el código de reinicio de Eric. De todos modos, estoy publicando mi versión, ¡espero que te guste!
@ECHO off
:: This script originally authored by Eric Falsken http://.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.
La solución de Eric Falsken funciona perfectamente. +1.
Pero me gustaría añadir que el comando de tiempo de espera a veces fallaría con el error: "La redirección de entrada no es compatible, saliendo del proceso de inmediato"
Para arreglar esto, tuve que reemplazar el comando timeout:
timeout /t 2 /nobreak >NUL
con lo siguiente:
ping -n 2 127.0.0.1 1>NUL
Los guiones de Eric Falsken son fantásticos para este propósito. Pero tenga en cuenta que utilizan el comando de tiempo de espera que solo está disponible en Vista / Server2003 y más reciente. Para una máquina XP, puede usar sleep.exe del Kit de recursos de NT en su lugar. (Esto debería ser un comentario a la respuesta de Eric pero no lo suficiente para hacerlo).
Mejoré el guión de Eric Falsken y lo revisé Gerorge Perkins.
Cambios:
- ahora no es solo un script de reinicio. El script puede iniciar, detener y reiniciar un servicio local o remoto;
- registro eliminado (si desea esto, puede usarlo simplemente iniciando SCRIPT_NAME.bat> logfile.txt);
optimizaciones dispersas.
@ECHO off :: This script originally authored by Eric Falsken http://.com/ :: Revised by George Perkins 10/20/2011 :: Revised by Armando Contestabile 02/23/2015 IF "%1"=="" GOTO Usage IF "%2"=="" GOTO Usage SET ACTION=%1 SET SERVICENAME=%2 IF "%3"=="" ( SET SYSTEMNAME=%COMPUTERNAME% ) ELSE ( SET SYSTEMNAME=%3 ) IF "%ACTION%" == "stop" ( SET ACTION=STOP ) ELSE IF "%ACTION%" == "STOP" ( SET ACTION=STOP ) ELSE IF "%ACTION%" == "start" ( SET ACTION=START ) ELSE IF "%ACTION%" == "START" ( SET ACTION=START ) ELSE IF "%ACTION%" == "restart" ( SET ACTION=RESTART ) ELSE IF "%ACTION%" == "RESTART" ( SET ACTION=RESTART ) ELSE GOTO Usage 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. ECHO Attempting to %ACTION% service %SERVICENAME% on computer %SYSTEMNAME%. PING -n 1 %SYSTEMNAME% | FIND "TTL=" >nul 2>&1 IF ERRORLEVEL 1 IF NOT ERRORLEVEL 2 ( ECHO Failure! Server //%SYSTEMNAME% or service %SERVICENAME% is not accessible or is offline! EXIT /B 1 ) SC //%SYSTEMNAME% query %SERVICENAME% | FIND "FAILED 1060" >nul 2>&1 IF ERRORLEVEL 0 IF NOT ERRORLEVEL 1 ( ECHO Failure! Service %SERVICENAME% is not valid! EXIT /B 2 ) SC //%SYSTEMNAME% query %SERVICENAME% | FIND "STATE" >nul 2>&1 IF ERRORLEVEL 1 IF NOT ERRORLEVEL 2 ( ECHO Failure! Server //%SYSTEMNAME% or service %SERVICENAME% is not accessible or is offline! EXIT /B 3 ) :Dispatch 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 of service is %CURRENT_STATUS% IF NOT "%CURRENT_STATUS%"=="RUNNING" IF NOT "%CURRENT_STATUS%"=="STOPPED" IF NOT "%CURRENT_STATUS%"=="PAUSED" ( IF "%SLEEP_COUNT%"=="%MAX_WAIT_PERIODS%" ( ECHO Service state won''t change. Script exececution is canceled. EXIT /B 4 ) ECHO Service State is changing, waiting %DEFAULT_DELAY% seconds... SLEEP %DEFAULT_DELAY% SET /A SLEEP_COUNT+=1 GOTO Dispatch ) IF "%ACTION%"=="START" ( IF "%CURRENT_STATUS%"=="RUNNING" ( ECHO Service %SERVICENAME% is running. GOTO EndExit ) ELSE ( GOTO StartService ) ) ELSE IF "%ACTION%"=="RESTART" ( IF "%CURRENT_STATUS%"=="RUNNING" ( IF %RESTARTED%==1 ( ECHO Service %SERVICENAME% restarted. GOTO EndExit ) SET /A SLEEP_COUNT=0 GOTO StopService ) ELSE ( SET /A RESTARTED=1 GOTO StartService ) ) ELSE IF "%ACTION%"=="STOP" ( IF "%CURRENT_STATUS%"=="STOPPED" ( ECHO Service %SERVICENAME% is stopped. GOTO EndExit ) ELSE ( GOTO StopService ) ) :StartService ECHO Starting %SERVICENAME% on //%SYSTEMNAME% SC //%SYSTEMNAME% start %SERVICENAME% >nul 2>&1 SET SLEEP_COUNT=0 GOTO Dispatch :StopService ECHO Stopping %SERVICENAME% on //%SYSTEMNAME% SC //%SYSTEMNAME% stop %SERVICENAME% >nul 2>&1 SET SLEEP_COUNT=0 GOTO Dispatch :Usage ECHO This script can start/stop/restart a local or remote service, waiting for the service to stop/start ^(if necessary^). ECHO. ECHO Usage: ECHO %0 ^<start^|stop^|restart^> ^<SERVICE^> [SYSTEM] ECHO. ECHO If no SYSTEM is provided, the script attempts to execute on the local system. EXIT /B 5 :EndExit ECHO. EXIT /B 0
No creo que puedas hacer esto con un comando directo dos. Puede consultar Code Project u otros sitios similares para ver si ya hay una solución personalizada para esto.
De lo contrario, podría escribir un servicio secundario de Windows que lo haga por usted al exponer la funcionalidad de inicio / detención a través de un punto final WCF. Para acceder a este servicio secundario de forma remota, puede escribir una aplicación de consola simple que se conecte a este servicio para iniciar / detener el servicio de Windows en cuestión. Dado que es una aplicación de consola, imitaría el comportamiento deseado de trabajar desde la línea de comandos y no regresar hasta que se complete (o se haya producido un error). No es la solución sencilla y simple que está buscando, pero la lanzaré para su consideración.
Nunca he visto algo que haga esto específicamente, pero sería bastante fácil eliminar dicha utilidad en C / C # / VB o en cualquier otro idioma que brinde fácil acceso a la API de servicio. Aquí hay una muestra de algo en 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 es solo un ciclo de votación y podría reemplazarse fácilmente en cualquier otro idioma. El resto es solo OpenService y ControlService.
NET START y NET STOP no deben regresar hasta que el servicio haya indicado que el servicio se ha iniciado o detenido con éxito.