Pergunta

Eu preciso escrever código robusto em .NET para habilitar um serviço do Windows (Server 2003) para reiniciar-se. Qual é a melhor maneira de modo que este? Existe alguma .NET API para fazê-lo?

Foi útil?

Solução

Definir o serviço para reiniciar após falha (clique duas vezes o serviço no painel de controle e dar uma olhada nessas abas - eu esqueci o nome dele). Então, sempre que desejar o serviço para reiniciar, apenas Environment.Exit(1) chamada (ou qualquer diferente de zero de retorno) e o sistema operacional irá reiniciá-lo para você.

Outras dicas

Dim proc As New Process()
Dim psi As New ProcessStartInfo()

psi.CreateNoWindow = True
psi.FileName = "cmd.exe"
psi.Arguments = "/C net stop YOURSERVICENAMEHERE && net start YOURSERVICENAMEHERE"
psi.LoadUserProfile = False
psi.UseShellExecute = False
psi.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo = psi
proc.Start()

Você não pode ter certeza de que a conta de usuário que o serviço está sendo executado em até tem permissões para parar e reiniciar o serviço.

Você pode criar um processo que é prompt de um comando DOS que reinicia-se:

 Process process = new Process();
 process.StartInfo.FileName = "cmd";
 process.StartInfo.Arguments = "/c net stop \"servicename\" & net start \"servicename\"";
 process.Start();
const string strCmdText = "/C net stop \"SERVICENAME\"&net start \"SERVICENAME\"";
Process.Start("CMD.exe", strCmdText);

onde SERVICENAME é o nome do seu serviço (aspas duplas incluídos na conta para espaços no nome do serviço, pode ser omitido em contrário).

Limpo, nenhuma configuração auto-restart necessário.

Isso dependeria por isso que você quer que ele reiniciar-se.

Se você está apenas procurando uma maneira de ter o serviço de limpar-se periodicamente, em seguida, você poderia ter um temporizador em execução no serviço que periodicamente faz uma rotina de purga.

Se você está procurando uma maneira de reiniciar em caso de falha -. O host de serviço em si pode fornecer essa capacidade quando se está configurado

Então, por que você precisa reiniciar o servidor? O que você está tentando alcançar?

Eu não acho que você pode em um serviço auto-suficiente (quando você chamar Restart, ele irá parar o serviço, que vai interromper o comando Restart, e isso nunca vai começar de novo). Se você pode adicionar uma segunda .exe (um aplicativo Console que usa a classe ServiceManager), então você pode lançar o exe autônomo e tê-lo reiniciar o serviço e depois sair.

Em segundo pensamento, você poderia provavelmente ter o serviço de registrar uma tarefa agendada (usando a linha de comando 'at' comando, por exemplo) para iniciar o serviço e, em seguida, tê-lo parar de si mesmo; que provavelmente iria funcionar.

O problema com a descascar para fora para um arquivo de lote ou EXE é que um serviço pode ou não ter as permissões necessárias para executar o aplicativo externo.

A maneira mais limpa de fazer isso que eu encontrei é usar o método OnStop (), que é o ponto de entrada para o Service Control Manager. Então todo o seu código de limpeza será executado, e você não terá quaisquer tomadas de suspensão ou outros processos, assumindo que o seu código de paragem está fazendo seu trabalho.

Para fazer isso, você precisa definir um sinalizador antes de terminar que informa o método OnStop para sair com um código de erro; em seguida, o SCM sabe que as necessidades de serviço para ser reiniciado. Sem essa bandeira que você não será capaz de parar o serviço manualmente a partir do SCM. Isso também pressupõe que você tenha configurado o serviço para reiniciar em um erro.

Aqui está o meu código de parada:

...

bool ABORT;

protected override void OnStop()
{
    Logger.log("Stopping service");
    WorkThreadRun = false;
    WorkThread.Join();
    Logger.stop();
    // if there was a problem, set an exit error code
    // so the service manager will restart this
    if(ABORT)Environment.Exit(1);
}

Se o serviço é executado em um problema e precisa ser reiniciado, eu lançar um segmento que interrompe o serviço do SCM. Isso permite que o serviço de limpar depois de si mesmo:

...

if(NeedToRestart)
{
    ABORT = true;
    new Thread(RestartThread).Start();
}

void RestartThread()
{
    ServiceController sc = new ServiceController(ServiceName);
    try
    {
        sc.Stop();
    }
    catch (Exception) { }
}

Gostaria de usar o Agendador do Windows para agendar um reinício do seu serviço. O problema é que você não pode reiniciar-se, mas você pode parar. (Você essencialmente serrou o ramo que você está sentado em ... se você pegar minha analogia) Você precisa de um processo separado para fazer isso por você. O Agendador do Windows é o mais adequado. Agendar uma tarefa de uma só vez para reiniciar o serviço (mesmo dentro do próprio serviço) para executar imediatamente.

Caso contrário, você terá que criar um processo de "pastorear" que faz isso por você.

Eu não acho que ele pode. Quando um serviço é "parado", ele fica totalmente descarregada.

Bem, OK, há sempre uma maneira que eu acho. Por exemplo, você pode criar um processo separado para parar o serviço, em seguida, reiniciá-lo, em seguida, sair.

A primeira resposta à pergunta é a solução mais simples: "Environment.Exit (1)" Eu estou usando isso no Windows Server 2008 R2 e ele funciona perfeitamente. O serviço pára si mesmo, o O / S espera de 1 minuto, em seguida, reinicia-lo.

Criar um appdomain separado para hospedar o código do aplicativo. Quando requer reinicialização, poderíamos descarregar e recarregar a appdomain vez o processo (serviço Windows). Isto é como IIS obras pool de aplicativo, eles não executar aplicativo asp.net diretamente, eles usam appdmain separado.

A melhor abordagem pode ser a de utilizar o Serviço NT como um wrapper para a sua aplicação. Quando o serviço de NT é iniciado, o aplicativo pode começar em um "idle" modo de espera para o comando para iniciar (ou ser configurado para iniciar automaticamente).

Pense em um carro, quando é iniciado, começa em um estado ocioso, à espera de seu comando para ir para a frente ou para trás. Isso também permite a outros benefícios, como melhor administração remota como você pode escolher a forma de expor a sua aplicação.

Apenas passando, e pensei que eu gostaria de acrescentar algumas informações adicionais ...

Você também pode lançar uma exceção, esta será automaticamente fechar o serviço janelas, ea auto re-iniciar opções de chutar. O único problema com isto é que se você tem um ambiente dev em seu PC, então as tentativas JIT chutar, e você vai ter uma depuração dizendo prompt de Y / N. dizer não e, em seguida, ele irá fechar, e em seguida, re-iniciar corretamente. (Em um PC sem JIT apenas tudo funciona). a razão im trolling, é este JIT é novo para Win 7 (que costumava funcionar bem com o XP etc) e estou tentando encontrar uma maneira de desativar o JIT .... i pode tentar o método Environment.Exit mencionado aqui ver como que funciona também.

Kristian: Bristol, Reino Unido

Crie um arquivo Restart.bat como este

@echo on
set once="C:\Program Files\MyService\once.bat"
set taskname=Restart_MyService
set service=MyService
echo rem %time% >%once%
echo net stop %service% >>%once%
echo net start %service% >>%once%
echo del %once% >>%once%

schtasks /create /ru "System" /tn %taskname% /tr '%once%' /sc onstart /F /V1 /Z
schtasks /run /tn %taskname%

Em seguida, exclua a tarefa% taskname% quando o seu serviço%% começa

NSSM é muito grande. ele vai fazer tudo isso para você

A maneira mais fácil é ter um arquivo de lote com:

net stop net start

e adicionar o arquivo para o programador com o seu tempo desejado intervalo

private static void  RestartService(string serviceName)
    {
        using (var controller = new ServiceController(serviceName))
        {
            controller.Stop();
            int counter = 0;
            while (controller.Status != ServiceControllerStatus.Stopped)
            {
                Thread.Sleep(100);
                controller.Refresh();
                counter++;
                if (counter > 1000)
                {
                    throw new System.TimeoutException(string.Format("Could not stop service: {0}", Constants.Series6Service.WindowsServiceName));
                }
            }

            controller.Start();
        }
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top