Parar e iniciar um serviço via lote ou arquivo cmd?

288

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)?

Keng
fonte
Talvez um pouco offtopic (desde que você solicite instruções bat & cmd), mas: O PowerShell fornece muito controle e feedback para executar ações como essa.
GvS 25/09/08

Respostas:

347

Use o SCcomando (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
Ferruccio
fonte
1
Concordo que isso é melhor do que o início / parada da rede. Observe que há uma opção para tocar também em serviços em máquinas remotas.
Outlaw Programmer
1
Ótima resposta. Mas você precisa ser administrador para executar o 'SC start service'. Eu encontrei uma solução para isso aqui (a resposta aceita contém a solução).
Michael K.
56
O problema com o SC é que o comando retorna imediatamente e não depois que a ação é concluída. Se você deseja reiniciar um serviço por meio de arquivo em lotes (parar e iniciar), a parada retorna imediatamente, a falha ocorre porque o serviço não está parado. A parada / inicialização da rede retorna após a conclusão da ação, portanto, não há esse problema.
Dom
Abri o cmd como modo de administrador, recebendo erro A sintaxe deste comando é: NET STOP serviço
Satish Singh
existe uma maneira de verificar se o serviço está parado corretamente? em 2020?
Anand Varkey Philips
212
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

Bill Michell
fonte
1
NET não é apenas para funções relacionadas ao serviço, mas SC é apenas para funções relacionadas ao serviço.
Wernight 04/07
3
Essa resposta é melhor porque o comando "net" bloqueia e aguarde o serviço iniciar ou parar antes que o script em lote continue em execução.
1716 Steven
Como (como o Edit diz) na maioria das vezes o errorlevelretorno é 2, veja aqui como interpretar o resultado do erro .
HeyJude 27/03
28

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.

Jonas Gulle
fonte
8

Em vez de verificar códigos, isso também funciona

net start "Apache tomcat" || goto ExitError

:End  
exit 0  

:ExitError  
echo An error has occurred while starting the tomcat services  
exit 1  
vanval
fonte
7

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
Nathanial Wilson
fonte
1
Normalmente, as respostas apenas de código não são apreciadas. Você poderia elaborar sua solução ou adicionar alguns comentários explicativos?
uma brincadeira
2
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ê.
Nathanial Wilson
6

Usar os códigos de retorno net starte me net stopparece o melhor método. Experimente o seguinte: Códigos de retorno do Net Start .

ZombieSheep
fonte
2
A página vinculada não existe mais. Como tal, isso é mais um comentário agora.
Neolisk
5

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
ATSiem
fonte
1
Como faço isso se precisar usar outro ID de usuário e senha para fazer logon?
Frantumn
1
Você executa CMDcomo 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.
user4317867
4

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.

DaveH
fonte
3

ou você pode iniciar o serviço remoto com este cmd: sc \\<computer> start <service>

cebolinha
fonte
3

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 starte net stopuse apenas errorlevel0 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 stoppara starte trabalhe ao contrário.

Clinton
fonte
3

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

Kuleris
fonte
2

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

djibe
fonte
1

SC pode fazer tudo com serviços ... iniciar, parar, verificar, configurar e muito mais ...

Axeman
fonte
1

À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
andrew pate
fonte
0

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.bate 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 msbuildcomando 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 :)

sh87
fonte