Como posso criar um script em um bastão ou cmd para parar e iniciar um serviço de forma confiável com a verificação de erros (ou me avise que não foi bem-sucedido por qualquer motivo)?
Como posso criar um script em um bastão ou cmd para parar e iniciar um serviço de forma confiável com a verificação de erros (ou me avise que não foi bem-sucedido por qualquer motivo)?
Respostas:
Use o SC
comando (service control), ele oferece muito mais opções do que apenas o start
& stop
.
DESCRIÇÃO: SC é um programa de linha de comando usado para comunicação com o NT Service Controller e serviços. USO: sc <servidor> [comando] [nome do serviço] ... A opção <server> possui o formato "\\ ServerName" Ajuda adicional sobre comandos pode ser obtida digitando: "sc [command]" Comandos: consulta ----------- Consulta o status de um serviço ou enumera o status para tipos de serviços. queryex --------- Consulta o status estendido de um serviço ou enumera o status para tipos de serviços. start ----------- Inicia um serviço. pausa ----------- Envia uma solicitação de controle PAUSE para um serviço. interrogate ----- Envia uma solicitação de controle INTERROGATE para um serviço. continue -------- Envia uma solicitação de controle CONTINUE para um serviço. stop ------------ Envia uma solicitação de interrupção para um serviço. config ---------- Altera a configuração de um serviço (persistente). descrição ----- Altera a descrição de um serviço. falha --------- Altera as ações executadas por um serviço em caso de falha. qc -------------- Consulta as informações de configuração de um serviço. qdescription ---- Consulta a descrição de um serviço. qfailure -------- Consulta as ações executadas por um serviço em caso de falha. delete ---------- Exclui um serviço (do registro). criar ---------- Cria um serviço. (adiciona ao registro). controle --------- Envia um controle para um serviço. sdshow ---------- Exibe o descritor de segurança de um serviço. sdset ----------- Define o descritor de segurança de um serviço. GetDisplayName - Obtém o DisplayName para um serviço. GetKeyName ------ Obtém o ServiceKeyName de um serviço. EnumDepend ------ Enumera dependências de serviço. Os seguintes comandos não requerem um nome de serviço: sc <servidor> <comando> <opção> boot ------------ (ok | incorreto) Indica se a última inicialização deve ser salvo como a última configuração de inicialização válida Bloquear ------------ Bloqueia o banco de dados de serviço QueryLock ------- Consulta o LockStatus para o banco de dados do SCManager EXEMPLO: sc inicia o MyService
net start [serviceName]
e
net stop [serviceName]
diga se eles tiveram sucesso ou falharam claramente. Por exemplo
U:\>net stop alerter
The Alerter service is not started.
More help is available by typing NET HELPMSG 3521.
Se estiver executando a partir de um arquivo em lotes, você terá acesso ao ERRORLEVEL do código de retorno. 0 indica sucesso. Qualquer coisa mais alta indica falha.
Como um arquivo bat, error.bat
:
@echo off
net stop alerter
if ERRORLEVEL 1 goto error
exit
:error
echo There was a problem
pause
A saída é assim:
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:
O comando NET não retorna os códigos de retorno da classe Win32_Service documentados (Serviço Inativo, Tempo Limite de Solicitação de Serviço, etc) e, para muitos erros, retornará simplesmente o Nível de Erro 2.
Veja aqui: http://ss64.com/nt/net_service.html
NET
não é apenas para funções relacionadas ao serviço, mas SC
é apenas para funções relacionadas ao serviço.
errorlevel
retorno é 2, veja aqui como interpretar o resultado do erro .
Você pode usar o comando NET START e depois verificar a variável de ambiente ERRORLEVEL, por exemplo
net start [your service]
if %errorlevel% == 2 echo Could not start service.
if %errorlevel% == 0 echo Service started successfully.
echo Errorlevel: %errorlevel%
Disclaimer: Eu escrevi isso do alto da minha cabeça, mas acho que vai funcionar.
Eu criei meu arquivo de lote pessoal para isso, o meu é um pouco diferente, mas fique à vontade para modificar como achar melhor. Eu criei isso há pouco tempo porque estava entediado e queria criar uma maneira simples de as pessoas poderem inserir final, iniciar, parar ou definir como automático. Este arquivo BAT simplesmente solicita que você insira o nome do serviço e fará o resto por você. Não percebi que ele estava procurando algo que indicava algum erro, devo ter interpretado mal essa parte. Embora normalmente isso possa ser feito, insira >> output.txt no final da linha.
O% var% é apenas uma maneira de o usuário poder inserir seu próprio serviço nisso, em vez de precisar modificar o arquivo bat toda vez que desejar iniciar / parar um serviço diferente.
Se eu estiver errado, qualquer um pode ficar à vontade para me corrigir.
@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 os códigos de retorno net start
e me net stop
parece o melhor método. Experimente o seguinte: Códigos de retorno do Net Start .
A sintaxe sempre me pega .... então ...
Aqui está explicitamente como adicionar uma linha a um arquivo em lotes que matará um serviço remoto (em outra máquina) se você for um administrador em ambas as máquinas, execute o .bat como administrador e as máquinas estejam no mesmo domínio. O nome da máquina segue o formato UNC \ myserver
sc \\ip.ip.ip.ip stop p4_1
Nesse caso ... p4_1 era o nome do serviço e o nome para exibição, quando você visualizava as propriedades do serviço no Service Manager. Você deve usar o nome do serviço.
Para os viciados em Operações de Serviço ... anexe seu código de razão e comente! ou seja, '4' igual a 'Planejado' e comente 'Parando o servidor para manutenção'
sc \\ip.ip.ip.ip stop p4_1 4 Stopping server for maintenance
CMD
como o outro usuário / ID runas /user:Domain\UserName cmd
, digitando sua senha. O CMD começará a ser executado como a conta de usuário especificada.
Gostaríamos de pensar que "net stop" interromperá o serviço. Infelizmente, a realidade não é tão preto e branco. Se o serviço demorar muito para parar, o comando retornará antes que o serviço pare. Você não saberá, a menos que verifique o nível de erro.
A solução parece fazer um loop, procurando o estado do serviço até que seja interrompido, com uma pausa cada vez que o loop for interrompido.
Mas, novamente ...
Estou vendo o primeiro serviço demorar muito tempo para parar, então o "net stop" para um serviço subseqüente parece não fazer nada. Observe o serviço no gerenciador de serviços e seu estado ainda é "Iniciado" - nenhuma alteração para "Parando". No entanto, eu posso parar este segundo serviço manualmente usando o SCM, e ele pára em 3 ou 4 segundos.
Acabei de usar o exemplo de Jonas acima e criei uma lista completa de 0 a 24 níveis de erro. Outra postagem está correta net start
e net stop
use apenas errorlevel
0 para o sucesso e 2 para falha.
Mas é isso que funcionou para mim:
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%
Mude stop
para start
e trabalhe ao contrário.
A reinicialização manual do serviço está ok - services.msc possui o botão "Reiniciar", mas na linha de comando os comandos sc e net não possuem uma opção "restart" e se a reinicialização estiver agendada no arquivo cmd / bat, o serviço será interrompido e iniciado imediatamente, às vezes recebe um erro porque o serviço ainda não foi interrompido, ele precisa de algum tempo para desligar as coisas.
Isso pode gerar um erro: sc stop sc start
É uma boa idéia inserir o tempo limite, eu uso ping (ele apita a cada 1 segundo): sc stop ping localhost -n 60 sc start
Aqui está o comando do Windows 10 para iniciar a Restauração do Sistema usando o lote:
sc config swprv start= Auto
Você também pode gostar desses comandos:
Altere o valor do registro para iniciar automaticamente a restauração do sistema
REG ADICIONAR "HKLM \ SOFTWARE \ Microsoft \ Windows \ Versão Atual \ SystemRestore" / v DisableSR / t REG_DWORD / d 0 / f
Crie um ponto de restauração do sistema
Wmic.exe / Namespace: \ root \ default Caminho SystemRestore Chame CreateRestorePoint "djibe salvou seu PC", 100, 12
Alterar o uso do disco de restauração do sistema
O vssadmin redimensiona o armazenamento de sombra / para = C: / on = C: / maxsize = 10%
Aproveitar
Às vezes você pode encontrar a parada não funciona ..
Meu SQlServer às vezes faz isso. O uso da seguinte linha de comando a mata. Se você realmente precisa do seu script para matar coisas que não param. Eu faria isso como último recurso
taskkill /pid [pid number] /f
Estou escrevendo um serviço do Windows em C #, o loop de parar / desinstalar / criar / instalar / iniciar ficou muito cansativo. Escrevi um mini script, chamei reploy.bat
e soltei no meu diretório de saída do Visual Studio (um que possui o serviço executável incorporado) para automatizar o loop.
Basta definir esses 3 Vars
servicename
: isso aparece no painel de controle do Windows Service (services.msc)
slndir
: pasta (não o caminho completo) que contém o arquivo da solução (.sln)
binpath
: caminho completo (não o caminho da pasta) para o serviço executável a partir da compilação
Observação: isso precisa ser executado a partir da linha de msbuild
comando do Visual Studio Developer para que o 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%
Talvez isso ajude alguém :)