Como capturar a saída do console de um serviço c #?

Temos um serviço C# implantado em um sistema cliente remoto. O aplicativo grava uma quantidade substancial de informações de "diagnóstico" no console (por exemplo, Console.WriteLine ()). O serviço não está "fazendo o que deveria". Como podemos capturar a saída do console do serviço em outro aplicativo?

Uma versão do WinForm, o aplicativo pode ser carregado no local do cliente. Infelizmente, funciona corretamente.

Atualizar:

Podemos alterar a alteração do serviço, mas preferimos não fazer grandes alterações no momento.

Também estamos registrando no MSMQ, mas apenas para eventos "importantes". Esse serviço interage com o MSMQ para suas operações normais. Ou pelo menos deveria. O serviço não parece estar puxando itens do MSMQ quando a versão do WinForm. Então, escrever as mensagens que estão indo para o console pode ser problemático.

18

7 Respostas

Você é capaz de alterar o código de serviço em todos os ? Nesse caso, usar o Console.SetOut para gravar em um arquivo seria o primeiro porto de chamada mais óbvio. Em seguida, mude para usando uma biblioteca de registro adequada para a próxima versão :)

31
adicionado
O uso do Console.SetOut foi uma alteração mínima suficiente que gerou informações suficientes para determinar o problema com o serviço.
adicionado o autor Mike Chess, fonte

Em geral, você deve evitar escrever informações de diagnóstico diretamente no Console, no Registro de Eventos, no MSMQ ou em qualquer outro lugar a partir do código do seu aplicativo. Em vez disso, chame uma API de registro e use a configuração para redirecionar a saída para onde você desejar.

Por exemplo, você pode substituir todo o Console.WriteLine por Trace.WriteLine (*). Em seguida, você pode redirecionar a saída para o console, um arquivo ou outro local, modificando o arquivo de configuração do aplicativo: por exemplo, para enviar para o console, use um ConsoleTraceListener, algo como:


  
    <trace autoflush="false" indentsize="4">
      
        
      
    
  
 

Durante a depuração, você obterá sua saída no console - no site do cliente, você a configuraria para redirecionar a saída de rastreamento para um arquivo, para o log de eventos ou semelhante.

Melhor ainda, use uma estrutura de registro de terceiros (eu recomendaria o Log4Net), que lhe dará mais opções do que o System.Diagnostics.Trace.

(*) Trace.Write/Trace.WriteLine são os mesmos que Debug.Write/Debug.WriteLine, exceto que os últimos só são compilados se o símbolo DEBUG for definido. Portanto, prefira Rastrear para Depurar se você deseja que a saída esteja disponível nas versões de Liberação.

12
adicionado

Você tem várias opções; O redirecionamento da saída do console para um arquivo e o uso de uma biblioteca de registro apropriada, como mencionado, são dois bons. Aqui está uma opção do meio: escreva no log de eventos.

EventLog log;
string logsource = "MyService";

// execute once per invocation
if (!System.Diagnostics.EventLog.SourceExists(logsource))
{
    System.Diagnostics.EventLog.CreateEventSource(
        logsource, "Application");
}
log = new EventLog();
log.Source = logsource;
log.Log = "Application";

// replace console logging with this
log.WriteEntry(message, EventLogEntryType.Information);

Then look for entries in the Application event log (Administrative Tools -> Event Viewer) where Source = "MyService".

5
adicionado

usar debug.writeline e usar o debugview sysinternals?

3
adicionado
ou log4net na próxima vez e configure o destino.
adicionado o autor kenny, fonte

Eu não usaria o Console.WriteLine de forma alguma a partir de um serviço de janela. Você provavelmente deve registrar esses erros em um arquivo de log.

Outra maneira de fazer isso para que vários aplicativos possam consumir os logs está enviando as mensagens de log para uma fila do MSMQ.

3
adicionado

Eu encontrei esta postagem no MSDN, que liga a saída do console a uma caixa de rich text, funcionou para mim com muita rapidez e facilidade.

Ele substitui WriteLine e pode ser expandido para substituir outros métodos.

1
adicionado

Aqui está como eu vi a saída do console de um serviço em execução no Windows 7. Isso pode ajudar se você não conseguir modificar o código-fonte do serviço para fazer o log em um arquivo.

  1. Execute o services.msc e edite as propriedades do serviço. Na guia "Logon", marque a opção "Permitir que o serviço interaja com a área de trabalho"

  2. Use o editor de registro para modificar o ImagePath do seu serviço: Vá para HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \ services \ [nome do seu serviço] e edite o ImagePath. Anexe cmd.exe/c ao início da cadeia do ImagePath. Portanto, se o seu ImagePath original for c: \ myService \ myservice.exe , seu novo ImagePath deverá ser cmd.exe /cc:\myService\myservice.exe.

  3. Inicie seu serviço. Você deve obter uma janela pop-up chamada "Detecção de serviços interativos". Selecione "Visualizar a mensagem". Sua tela deve alternar contextos e exibir a janela do console. Quando terminar, clique no botão "Voltar agora".

  4. Quando terminar a depuração, modifique o ImagePath de volta ao seu valor original. Em seguida, desmarque a caixa de seleção "Permitir que o serviço interaja com a área de trabalho" nas propriedades do serviço e reinicie o serviço.

Aviso: Eu só fiz isso com um serviço e funcionou para mim. Não sei se funcionará para qualquer serviço ou se causará resultados inesperados, por isso sugiro que você faça isso apenas em um ambiente que não seja de produção.

1
adicionado