Instale o serviço do Windows com ação de recuperação para reiniciar

88

Estou instalando um serviço do Windows usando as classes ServiceProcessInstallere ServiceInstaller.

Usei o ServiceProcessInstallerpara definir o tipo de início, nome, etc. Mas como faço para definir a ação de recuperação para reiniciar?

Sei que posso fazer isso manualmente após a instalação do serviço, acessando o console de gerenciamento de serviços e alterando as configurações na guia de recuperação das propriedades do serviço, mas há uma maneira de fazer isso durante a instalação?

Guia de recuperação de propriedade de serviço

Raio
fonte

Respostas:

99

Você pode definir as opções de recuperação usando sc . O seguinte configurará o serviço para reiniciar após uma falha:

sc failure [servicename] reset= 0 actions= restart/60000

Isso pode ser facilmente chamado de C #:

static void SetRecoveryOptions(string serviceName)
{
    int exitCode;
    using (var process = new Process())
    {
        var startInfo = process.StartInfo;
        startInfo.FileName = "sc";
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;

        // tell Windows that the service should restart if it fails
        startInfo.Arguments = string.Format("failure \"{0}\" reset= 0 actions= restart/60000", serviceName);

        process.Start();
        process.WaitForExit();

        exitCode = process.ExitCode;
    }

    if (exitCode != 0)
        throw new InvalidOperationException();
}
Kevin
fonte
4
Observe que você precisa incluir o nome do serviço entre aspas, se contiver espaços.
user626528
19
Se você for chamar isso do manipulador de instalação do serviço Installer [] em C # quando o serviço for instalado, você pode inserir essa chamada no manipulador de eventos "Committed", que irá executá-lo logo após o serviço aparecer no Service Control Manager. Não o coloque no gerenciador de eventos "AfterInstall", pois ele não funcionará na primeira vez que o serviço for instalado na caixa.
Contango
A análise de código do @Kevin Visual Studio sugere que os objetos não devem ser descartados mais de uma vez, a process.Close()linha é inútil.
JohnTube
1
@ JohnTube - removeu a linha process.Close ()
Kevin
23
Observe que a sintaxe pode parecer estranha para alguns, mas reset= 0está correta e reset=0está incorreta. O uso correto dos espaços é crucial, reset=é um argumento, seguido de um espaço, então 0.
Liam,
12

Depois de muitas tentativas, resolvi isso usando o aplicativo de linha de comando sc .

Eu tenho um arquivo em lote com installutil e sc. Meu arquivo de lote é semelhante a:

installutil.exe "path to your service.exe"
sc failure "your service name" reset= 300 command= "some exe file to execute" actions= restart/20000/run/1000/reboot/1000

Se você deseja a documentação completa do comando sc, siga este link: SC.exe: comunica-se com o controlador de serviço e serviços instalados

Observação: você precisa adicionar um espaço após cada símbolo de igual (=). Exemplo: reset = 300

Juan Carlos Velez
fonte