2008-10-14 40 views
18

Tenemos un servicio C# que se implementa en un sistema de cliente remoto. La aplicación escribe una cantidad sustancial de información de "diagnóstico" en la consola (es decir, Console.WriteLine()). El servicio no está "haciendo lo que debería". ¿Cómo podemos capturar la salida de la consola del servicio en otra aplicación?Cómo capturar la salida de consola de un servicio C#?

Una versión de WinForm la aplicación se puede cargar en la ubicación del cliente. Desafortunadamente, funciona correctamente.

Actualización:

somos capaces de cambiar el cambio del servicio, pero prefiere no hacer cambios importantes en este momento.

También estamos iniciando sesión en MSMQ, pero solo para eventos "importantes". Este servicio interactúa con MSMQ para sus operaciones normales. O al menos debería. El servicio no parece extraer elementos de MSMQ cuando lo hace la versión de WinForm. Entonces, escribir los mensajes que van a la consola podría ser problemático.

Respuesta

31

¿Puede cambiar el código de servicio al? Si es así, usar Console.SetOut para escribir en un archivo sería el primer puerto de escala más obvio. Luego cambie a usar una biblioteca de registro apropiada para la próxima versión :)

+2

Uso de Console.SetOut fue un cambio lo suficientemente mínimo que proporcionó información suficiente para determinar el problema con el servicio. –

3

No utilizaría Console.WriteLine en absoluto desde un Servicio de Ventanas. Probablemente deberías registrar estos errores en un archivo de registro.

Otra forma de hacer esto para que varias aplicaciones puedan consumir los registros es publicar los mensajes de registro en una cola de MSMQ.

3

use debug.writeline y use la depuración de sysinternals?

+1

o log4net la próxima vez y configure el destino. – kenny

5

Tienes un montón de opciones; redirigir la salida de la consola a un archivo y usar una biblioteca de registro apropiada como se mencionó son dos buenas. Aquí hay una opción del medio: escriba en el registro 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); 

luego buscar entradas en el registro de sucesos de aplicación (Herramientas administrativas -> Visor de sucesos), donde la Fuente = "MyService".

12

En general, debe evitar escribir información de diagnóstico directamente en la consola, el registro de eventos, MSMQ o en otro lugar desde el código de la aplicación. En su lugar, llame a una API de registro y use la configuración para redirigir el resultado donde desee.

Por ejemplo, puede reemplazar todas las Console.WriteLine por Trace.WriteLine (*). A continuación, puede redirigir la salida a la consola, un archivo o en otro lugar modificando el archivo de configuración de la aplicación: por ejemplo, a la salida de la consola, use un ConsoleTraceListener, algo así como:

<configuration> 
    <system.diagnostics> 
    <trace autoflush="false" indentsize="4"> 
     <listeners> 
     <add name="configConsoleListener" 
      type="System.Diagnostics.ConsoleTraceListener" /> 
     </listeners> 
    </trace> 
    </system.diagnostics> 
</configuration> 

Durante la depuración, que obtendrá su salida en la consola: en el sitio del cliente, lo configuraría para redirigir la salida de rastreo a un archivo, al registro de eventos o similar.

Mejor aún, utilice un marco de registro de terceros (recomendaría Log4Net) que le ofrecerá más opciones que System.Diagnostics.Trace.

(*) Trace.Write/Trace.WriteLine son lo mismo que Debug.Write/Debug.WriteLine, excepto que estos últimos solo se compilan si se define el símbolo DEBUG. Por lo tanto, prefiera Trace a Debug si desea que la salida esté disponible en las compilaciones de Release.

1

Encontré this post en MSDN que vincula la salida de la Consola a un cuadro de texto enriquecido, funcionó para mí de manera rápida y fácil.

Anula WriteLine, y podría ampliarse para anular otros métodos.

1

Así es como vi la salida de consola de un servicio que se ejecuta en Windows 7. Esto podría ayudar si no puede modificar el código fuente del servicio para iniciar sesión en un archivo.

  1. Ejecute services.msc y edite las propiedades del servicio. En la pestaña "Iniciar sesión", marque la casilla "Permitir que el servicio interactúe con el escritorio"

  2. Use el editor de registro para modificar ImagePath de su servicio: vaya a HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \ services \ [your service name] y editar ImagePath. Añada cmd.exe /c al comienzo de la cadena de ImagePath. Entonces, si su ImagePath original es c:\myService\myservice.exe, su nuevo ImagePath debe ser cmd.exe /c c:\myService\myservice.exe.

  3. Comience su servicio. Debería obtener una ventana emergente titulada "Detección de servicios interactivos". Seleccione "Ver el mensaje". Su pantalla debe cambiar contextos y mostrar la ventana de la consola. Cuando termine, haga clic en el botón "Volver ahora".

  4. Cuando termine la depuración, modifique ImagePath a su valor original. A continuación, desmarque la casilla "Permitir que el servicio interactúe con el escritorio" en las propiedades del servicio y reinicie su servicio.

Advertencia: Solo he hecho esto con un servicio y funcionó para mí. No sé si funcionará para cualquier servicio o si causará resultados inesperados, por lo que le sugiero que solo lo haga en un entorno que no sea de producción.

Cuestiones relacionadas