¿Cómo puedo escribir un bat o cmd para detener e iniciar un servicio de manera confiable con la comprobación de errores (o informarme que no fue exitoso por alguna razón)?
¿Cómo puedo escribir un bat o cmd para detener e iniciar un servicio de manera confiable con la comprobación de errores (o informarme que no fue exitoso por alguna razón)?
Respuestas:
Use el SC
comando (control de servicio), le brinda muchas más opciones que solo start
& stop
.
DESCRIPCIÓN: SC es un programa de línea de comando utilizado para comunicarse con el NT Service Controller y servicios. USO: sc <servidor> [comando] [nombre del servicio] ... La opción <server> tiene la forma "\\ ServerName" Puede obtener más ayuda sobre los comandos escribiendo: "sc [comando]" Comandos: consulta ----------- Consulta el estado de un servicio, o enumera el estado de los tipos de servicios. queryex --------- Consulta el estado extendido de un servicio, o enumera el estado de los tipos de servicios. inicio ----------- Inicia un servicio. pausa ----------- Envía una solicitud de control PAUSE a un servicio. interrogar ----- Envía una solicitud de control INTERROGATE a un servicio. continuar -------- Envía una solicitud de control CONTINUAR a un servicio. stop ------------ Envía una solicitud STOP a un servicio. config ---------- Cambia la configuración de un servicio (persistente). description ----- Cambia la descripción de un servicio. falla --------- Cambia las acciones tomadas por un servicio en caso de falla. qc -------------- Consulta la información de configuración de un servicio. qdescription ---- Consulta la descripción de un servicio. qfailure -------- Consulta las acciones tomadas por un servicio en caso de falla. eliminar ---------- Elimina un servicio (del registro). crear ---------- Crea un servicio. (lo agrega al registro). control --------- Envía un control a un servicio. sdshow ---------- Muestra el descriptor de seguridad de un servicio. sdset ----------- Establece el descriptor de seguridad de un servicio. GetDisplayName: obtiene el DisplayName para un servicio. GetKeyName ------ Obtiene ServiceKeyName para un servicio. EnumDepend ------ Enumera las dependencias de servicio. Los siguientes comandos no requieren un nombre de servicio: sc <servidor> <comando> <opción> boot ------------ (ok | bad) Indica si el último arranque debería guardarse como la última configuración de arranque válida conocida Bloquear ------------ Bloquea la base de datos del servicio QueryLock ------- Consulta el LockStatus para la base de datos SCManager EJEMPLO: sc iniciar MyService
net start [serviceName]
y
net stop [serviceName]
decirle si han tenido éxito o fallado con bastante claridad. Por ejemplo
U:\>net stop alerter
The Alerter service is not started.
More help is available by typing NET HELPMSG 3521.
Si se ejecuta desde un archivo por lotes, tiene acceso al ERRORLEVEL del código de retorno. 0 indica éxito. Cualquier cosa más alta indica fracaso.
Como un archivo bat error.bat
:
@echo off
net stop alerter
if ERRORLEVEL 1 goto error
exit
:error
echo There was a problem
pause
El resultado se ve así:
U:\>error.bat
The Alerter service is not started.
More help is available by typing NET HELPMSG 3521.
There was a problem
Press any key to continue . . .
Códigos de retorno
- 0 = Success
- 1 = Not Supported
- 2 = Access Denied
- 3 = Dependent Services Running
- 4 = Invalid Service Control
- 5 = Service Cannot Accept Control
- 6 = Service Not Active
- 7 = Service Request Timeout
- 8 = Unknown Failure
- 9 = Path Not Found
- 10 = Service Already Running
- 11 = Service Database Locked
- 12 = Service Dependency Deleted
- 13 = Service Dependency Failure
- 14 = Service Disabled
- 15 = Service Logon Failure
- 16 = Service Marked For Deletion
- 17 = Service No Thread
- 18 = Status Circular Dependency
- 19 = Status Duplicate Name
- 20 = Status Invalid Name
- 21 = Status Invalid Parameter
- 22 = Status Invalid Service Account
- 23 = Status Service Exists
- 24 = Service Already Paused
Editar 20.04.2015
Códigos de retorno:
El comando NET no devuelve los códigos de retorno documentados de la clase Win32_Service (Servicio no activo, Tiempo de espera de solicitud de servicio, etc.) y para muchos errores simplemente devolverá Errorlevel 2.
Mire aquí: http://ss64.com/nt/net_service.html
NET
no es solo para funciones relacionadas con el servicio, mientras que SC
es solo para funciones relacionadas con el servicio.
errorlevel
devuelto es 2, vea aquí cómo interpretar el resultado del error .
Puede usar el comando NET START y luego verificar la variable de entorno ERRORLEVEL, p. Ej.
net start [your service]
if %errorlevel% == 2 echo Could not start service.
if %errorlevel% == 0 echo Service started successfully.
echo Errorlevel: %errorlevel%
Descargo de responsabilidad: he escrito esto desde la parte superior de mi cabeza, pero creo que funcionará.
He creado mi archivo por lotes personal para esto, el mío es un poco diferente, pero puede modificarlo como mejor le parezca. Creé esto hace un tiempo porque estaba aburrido y quería hacer una manera simple para que las personas pudieran ingresar el final, el inicio, la detención o la configuración en automático. Este archivo BAT simplemente le solicita que ingrese el nombre del servicio y hará el resto por usted. No me di cuenta de que estaba buscando algo que indicara algún error, debo haber leído mal esa parte. Aunque normalmente esto se puede hacer ingresando >> output.txt al final de la línea.
El% var% es solo una forma para que el usuario pueda ingresar su propio servicio en este, en lugar de tener que modificar el archivo bat cada vez que desee iniciar / detener un servicio diferente.
Si me equivoco, cualquiera puede sentirse libre de corregirme al respecto.
@echo off
set /p c= Would you like to start a service [Y/N]?
if /I "%c%" EQU "Y" goto :1
if /I "%c%" EQU "N" goto :2
:1
set /p var= Service name:
:2
set /p c= Would you like to stop a service [Y/N]?
if /I "%c%" EQU "Y" goto :3
if /I "%c%" EQU "N" goto :4
:3
set /p var1= Service name:
:4
set /p c= Would you like to disable a service [Y/N]?
if /I "%c%" EQU "Y" goto :5
if /I "%c%" EQU "N" goto :6
:5
set /p var2= Service name:
:6
set /p c= Would you like to set a service to auto [Y/N]?
if /I "%c%" EQU "Y" goto :7
if /I "%c%" EQU "N" goto :10
:7
set /p var3= Service name:
:10
sc start %var%
sc stop %var1%
sc config %var2% start=disabled
sc config %var3% start=auto
Usar los códigos de retorno de net start
y me net stop
parece el mejor método. Pruebe esto: los códigos de retorno de Net Start .
La sintaxis siempre me atrapa ... así que ...
Aquí se explica explícitamente cómo agregar una línea a un archivo por lotes que eliminará un servicio remoto (en otra máquina) si es administrador en ambas máquinas, ejecute .bat como administrador y las máquinas estén en el mismo dominio. El nombre de la máquina sigue el formato UNC \ myserver
sc \\ip.ip.ip.ip stop p4_1
En este caso ... p4_1 era tanto el Nombre del servicio como el Nombre para mostrar, cuando ve las Propiedades del servicio en el Administrador de servicios. Debe usar el nombre del servicio.
Para sus adictos a Service Ops ... ¡asegúrese de agregar su código de razón y comentar! es decir, '4' que equivale a 'Planificado' y comentar 'Detener el servidor por mantenimiento'
sc \\ip.ip.ip.ip stop p4_1 4 Stopping server for maintenance
CMD
como el otro usuario / ID y runas /user:Domain\UserName cmd
luego ingresas tu contraseña. CMD comenzará a ejecutarse como la cuenta de usuario especificada.
Nos gustaría pensar que "net stop" detendrá el servicio. Lamentablemente, la realidad no es tan en blanco y negro. Si el servicio tarda mucho en detenerse, el comando volverá antes de que se detenga. Sin embargo, no lo sabrá, a menos que marque el nivel de error.
La solución parece ser recorrer todo el ciclo buscando el estado del servicio hasta que se detenga, con una pausa cada vez que se completa el ciclo.
Pero entonces de nuevo...
Estoy viendo que el primer servicio tarda mucho en detenerse, luego la "parada neta" para un servicio posterior parece no hacer nada. Mire el servicio en el administrador de servicios, y su estado todavía está "Iniciado", sin cambios en "Deteniendo". Sin embargo, puedo detener este segundo servicio manualmente usando el SCM, y se detiene en 3 o 4 segundos.
Acabo de usar el ejemplo anterior de Jonas y creé una lista completa de 0 a 24 niveles de error. Otra publicación es correcta net start
y net stop
solo usa errorlevel
0 para el éxito y 2 para el fracaso.
Pero esto es lo que funcionó para mí:
net stop postgresql-9.1
if %errorlevel% == 2 echo Access Denied - Could not stop service
if %errorlevel% == 0 echo Service stopped successfully
echo Errorlevel: %errorlevel%
Cambiar stop
a start
y funciona a la inversa.
El reinicio manual del servicio está bien: services.msc tiene el botón "Reiniciar", pero en la línea de comando los comandos sc y net carecen de un interruptor "reiniciar" y si el reinicio está programado en el archivo cmd / bat, el servicio se detiene y se inicia de inmediato, a veces recibe un error porque el servicio aún no se ha detenido, necesita algo de tiempo para apagar las cosas.
Esto puede generar un error: sc stop sc start
Es una buena idea insertar tiempo de espera, utilizo ping (suena cada 1 segundo): sc stop ping localhost -n 60 sc start
Aquí está el comando de Windows 10 para iniciar Restaurar sistema usando lote:
sc config swprv start= Auto
También te pueden gustar esos comandos:
Cambiar el valor del registro para iniciar automáticamente la restauración del sistema
REG AÑADIR "HKLM \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ SystemRestore" / v DisableSR / t REG_DWORD / d 0 / f
Crear un punto de restauración del sistema
Wmic.exe / Namespace: \ root \ default Ruta SystemRestore Llame a CreateRestorePoint "djibe salvó su PC", 100, 12
Cambiar el uso del disco de Restaurar sistema
vssadmin cambiar el tamaño del almacenamiento de sombras / for = C: / on = C: / maxsize = 10%
Disfrutar
A veces puedes encontrar que la parada no funciona.
Mi SQlServer a veces hace esto. Usar la siguiente línea de comando lo mata. Si realmente necesitas tu script para matar cosas que no se detienen. Me gustaría que hiciera esto como último recurso
taskkill /pid [pid number] /f
Estoy escribiendo un servicio de Windows en C #, el ciclo de detención / desinstalación / compilación / instalación / inicio se cansó demasiado. Escribí un mini script, lo llamé reploy.bat
y lo coloqué en mi directorio de salida de Visual Studio (uno que tiene el ejecutable del servicio integrado) para automatizar el bucle.
Solo configura estos 3 vars
servicename
: esto aparece en el panel de control del Servicio de Windows (services.msc)
slndir
: carpeta (no la ruta completa) que contiene su archivo de solución (.sln)
binpath
: ruta completa (no la ruta de la carpeta) al servicio ejecutable desde la compilación
NOTA: Esto debe ejecutarse desde la línea de comandos del desarrollador de Visual Studio para que el msbuild
comando funcione.
SET servicename="My Amazing Service"
SET slndir="C:dir\that\contains\sln\file"
SET binpath="C:path\to\service.exe"
SET currdir=%cd%
call net stop %servicename%
call sc delete %servicename%
cd %slndir%
call msbuild
cd %bindir%
call sc create %servicename% binpath=%binpath%
call net start %servicename%
cd %currdir%
Tal vez esto ayude a alguien :)