O serviço do Windows no computador local foi iniciado e depois parou de erro

105

Normalmente, recebo este erro: (O serviço "nome do serviço" no Computador Local foi iniciado e depois interrompido. Alguns serviços param automaticamente se não estiverem em uso por outro serviço ou programa) quando há algo errado com meu código, como inexistente caminhos da unidade, etc. O serviço do Windows não será iniciado.

Eu tenho um serviço do Windows que faz backup de pastas / arquivos em um local se atingiu o limite de tamanho. Os detalhes são fornecidos por uma configuração XML que o serviço do Windows lê na inicialização. Eu tenho um windows forms separado que tem um botão que faz exatamente o que o onstart do meu serviço do Windows está fazendo. Eu uso meus formulários do Windows para depurar o código antes de colocá-lo no serviço do Windows.

Quando eu inicio o meu windows forms. Ele faz o que deveria fazer. Quando coloquei meu código no método OnStart () do serviço do Windows, o erro apareceu.

Este é o meu código:

protected override void OnStart(string[] args)
{

    private static string backupConfig = @"D:\LogBackupConfig\backupconfig.xml";
    private static string serviceStat = @"D:\LogBackupConfig\Status.txt";
    private static string fileFolderStat = @"D:\LogBackupConfig\FileFolderStat.txt";

    protected override void OnStart(string[] args)
    {
        if (File.Exists(backupConfig))
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            XmlTextReader reader = new XmlTextReader(backupConfig);

            XmlNodeType type;
            List<string> listFile = new List<string>();
            string fileWatch = "";

            //this loop is for reading XML elements and assigning to variables
            while (reader.Read())
            {
                type = reader.NodeType;
                if (type == XmlNodeType.Element)
                {
                    if (reader.Name == "File")
                    {
                        reader.Read();
                        fileWatch = reader.Value;
                    }
                    else if (reader.Name == "Folder")
                    {
                        reader.Read();
                        fileWatch = reader.Value;
                    }
                }
            }
            reader.Close();

            watcher.Path = fileWatch;
            watcher.Filter = "*.*";

            //this loop reads whether the service will watch a file/folder
            XmlTextReader reader1 = new XmlTextReader(backupConfig);
            while (reader1.Read())
            {
                type = reader1.NodeType;
                if (type == XmlNodeType.Element)
                {
                    if (reader1.Name == "File")
                    {
                        watcher.IncludeSubdirectories = false;
                        watcher.Changed += new FileSystemEventHandler(OnChangedFile);
                    }
                    else if (reader1.Name == "Folder")
                    {
                        watcher.IncludeSubdirectories = true;
                        watcher.Changed += new FileSystemEventHandler(OnChangedFolder);
                    }
                }
            }
            reader1.Close();

            watcher.EnableRaisingEvents = true;

        }
        else
        {
            StreamWriter sw = new StreamWriter(serviceStat, true);
            sw.WriteLine("File not found. Please start the Log Backup UI first.");
            sw.Close();
        }
    }

Não sei o que impede o serviço do Windows de iniciar, o simulador do Windows Form funcionou bem. Oque parece ser o problema?

ATUALIZAÇÃO: Depois de muitas tentativas, notei que usando apenas um diretório de pasta (sem arquivo), o serviço do Windows não funciona. Quando substituí a variável fileWatch por um arquivo específico (incluindo seu diretório), o serviço do Windows foi iniciado. Quando mudei de volta para um local de pasta, não funcionou. O que eu acho é que os locais das pastas não funcionam em um arquivador.

Quando tentei criar um novo serviço do Windows que vigia o local de uma pasta, funcionou. No entanto, quando tentei o mesmo local no meu serviço do Windows original, não funcionou! Eu estava pensando! Parece que tenho que criar um novo serviço do Windows e construir o instalador toda vez que coloco um novo código / função. Desta forma, posso acompanhar onde recebo um erro.

Blackator
fonte

Respostas:

203

Se o serviço iniciar e parar assim, significa que seu código está lançando uma exceção não tratada. Isso é muito difícil de depurar, mas existem algumas opções.

  1. Consulte o Visualizador de eventos do Windows . Normalmente, você pode fazer isso acessando o gerenciador do computador / servidor e clicando em Visualizador de eventos -> Logs do Windows -> Aplicativo . Você pode ver o que gerou a exceção aqui, o que pode ajudar, mas você não obtém o rastreamento de pilha.
  2. Extraia a lógica do programa em um projeto de classe de biblioteca. Agora crie duas versões diferentes do programa: um aplicativo de console (para depuração) e o serviço do Windows. (Este é um pouco de esforço inicial, mas evita muita angústia a longo prazo.)
  3. Adicione mais blocos try / catch e registro no aplicativo para obter uma imagem melhor do que está acontecendo.
McGarnagle
fonte
10
O Visualizador de Eventos do Windows mostrou o rastreamento de pilha completo, uma ferramenta muito útil.
Talha Imam
37

Não tenho certeza se isso será útil, mas para depurar um serviço você sempre pode usar o seguinte no método OnStart:

protected override void OnStart(string[] args)
{
     System.Diagnostics.Debugger.Launch();
     ...
}

do que você poderia anexar seu estúdio visual ao processo e ter melhores habilidades de depuração.

espero que tenha sido útil, boa sorte

Eyal H
fonte
Esta é de longe a melhor solução (pelo menos para mim). O VS 2015 também lida com isso muito bem. Para mim, apareceu uma caixa de diálogo de confirmação do UAC para o depurador JIT e, em seguida, deixe-me selecionar o VS 2015 como o depurador.
Smitty de
9

Achei muito útil converter seu serviço do Windows existente em um console simplesmente alterando seu programa com o seguinte. Com essa mudança, você pode executar o programa depurando no Visual Studio ou executando o executável normalmente. Mas também funcionará como um serviço do Windows. Eu também fiz uma postagem no blog sobre isso

program.cs

class Program
{
    static void Main()
    {
        var program = new YOUR_PROGRAM();
        if (Environment.UserInteractive)
        {
            program.Start();
        }
        else
        {
            ServiceBase.Run(new ServiceBase[]
            {
                program
            });
        }
    }
}

YOUR_PROGRAM.cs

[RunInstallerAttribute(true)]
public class YOUR_PROGRAM : ServiceBase
{
    public YOUR_PROGRAM()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        Start();
    }

    protected override void OnStop()
    {
        //Stop Logic Here
    }

    public void Start()
    {
        //Start Logic here
    }
}
Ben Anderson
fonte
2

EventLog.Log deve ser definido como "Application"

panini pitke
fonte
Acabei de votar porque esta era realmente a solução para o meu problema
Savage
1

Enquanto isso, outro motivo: excluído acidentalmente o arquivo .config causou a mesma mensagem de erro aparecer:

"O serviço no computador local foi iniciado e interrompido. Alguns serviços param automaticamente ..."

Emre Guldogan
fonte
0

Use o cronômetro e o evento de marcação para copiar seus arquivos.

Ao iniciar o serviço, inicie o horário e especifique o intervalo no horário.

Assim, o serviço continua rodando e copia os arquivos ontick.

Espero que ajude.

Sethu
fonte
0

Você pode querer fazer o teste de unidade da inicialização - mas, como está no OnStartmétodo, isso é quase impossível. Eu sugeriria mover o código de inicialização para uma classe separada para que ele possa ser testado ou pelo menos reutilizado em um testador de formulário.

Em segundo lugar, adicionar algum registro (usando Log4Net ou similar) e adicionar algum registro detalhado para que você possa ver detalhes sobre erros de tempo de execução. Exemplos de erros de tempo de execução seriam AccessViolationetc., especialmente se seu serviço estiver sendo executado sem privilégios suficientes para acessar os arquivos de configuração.

Quinton Bernhardt
fonte
0

A conta que está executando o serviço pode não ter mapeado a unidade D: (eles são específicos do usuário). Tente compartilhar o diretório e use o caminho UNC completo no seu backupConfig.

Seu watcherdo tipo FileSystemWatcheré uma variável local e está fora do escopo quando o OnStartmétodo é concluído. Você provavelmente precisará dele como uma instância ou variável de classe.

Alf Kåre Lefdal
fonte
0

Eu me deparei com o mesmo problema. Meu serviço está enviando / recebendo XMLS e gravando os erros no log de eventos.

Quando fui para o Registro de eventos, tentei filtrá-lo. Ele me avisou que o Log de eventos estava corrompido.

Limpei o registro de eventos e tudo OK.

PanosPlat
fonte
0

Em nosso caso, nada foi adicionado aos Logs de Eventos do Windows, exceto os logs de que o serviço problemático foi iniciado e interrompido.

Acontece que o arquivo CONFIG do serviço era inválido. A correção do arquivo CONFIG inválido corrigiu o problema.

rikitikitik
fonte