如何从服务C#捕获控制台输出?

如何从服务C#捕获控制台输出?,c#,service,console,C#,Service,Console,我们有一个部署到远程客户系统的C#服务。应用程序将大量“诊断”信息写入控制台(即console.WriteLine())。该服务没有“做它应该做的”。我们如何在另一个应用程序中捕获该服务的控制台输出 WinForm版本可以在客户位置加载应用程序。不幸的是,它工作正常 更新: 我们可以更改服务,但不希望在此时进行重大更改 我们也在登录MSMQ,但只针对“重要”事件。此服务确实与MSMQ进行交互以实现其正常操作。或者,至少,它应该这样做。当WinForm版本从MSMQ提取项目时,该服务似乎没有从MS

我们有一个部署到远程客户系统的C#服务。应用程序将大量“诊断”信息写入控制台(即console.WriteLine())。该服务没有“做它应该做的”。我们如何在另一个应用程序中捕获该服务的控制台输出

WinForm版本可以在客户位置加载应用程序。不幸的是,它工作正常

更新:

我们可以更改服务,但不希望在此时进行重大更改


我们也在登录MSMQ,但只针对“重要”事件。此服务确实与MSMQ进行交互以实现其正常操作。或者,至少,它应该这样做。当WinForm版本从MSMQ提取项目时,该服务似乎没有从MSMQ提取项目。因此,编写发送到控制台的消息可能会有问题。

您是否能够更改服务代码?如果是这样,那么使用Console.SetOut来写入文件将是最明显的第一个调用端口。然后改为在下一版本中使用适当的日志库:)

我根本不会从窗口服务使用Console.WriteLine。您可能应该将这些错误记录到日志文件中


另一种使多个应用程序可以使用日志的方法是将日志消息发布到MSMQ队列。

使用debug.writeline并使用sysinternals debugview?

您有很多选项;如前所述,将控制台输出重定向到文件和使用适当的日志库是两个好方法。这里有一个中间选项:写入事件日志

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);

然后在应用程序事件日志(管理工具->事件查看器)中查找条目,其中Source=“MyService”。

通常,您应该避免将诊断信息直接写入控制台、事件日志、MSMQ或应用程序代码中的其他位置。而是调用一个日志API,并使用配置将输出重定向到任何您想要的地方

例如,您可以用Trace.WriteLine(*)替换所有Console.WriteLine。然后,您可以通过修改应用程序配置文件将输出重定向到控制台、文件或其他位置:例如,要输出到控制台,请使用ConsoleTraceListener,类似于:

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

调试时,您将在控制台上获得输出—在客户站点上,您将配置它以将跟踪输出重定向到文件、事件日志或类似文件

更好的是,使用第三方日志框架(我建议使用Log4Net),它将为您提供比System.Diagnostics.Trace更多的选项

(*)Trace.Write/Trace.WriteLine与Debug.Write/Debug.WriteLine相同,只是后者仅在定义调试符号时才编译。因此,如果希望输出在发布版本中可用,则更喜欢跟踪而不是调试。

我在MSDN上找到了它,它将控制台输出绑定到一个富文本框,对我来说非常方便快捷


它覆盖WriteLine,并且可以扩展为覆盖其他方法。

以下是我如何查看在Windows 7下运行的服务的控制台输出。如果您完全无法修改服务的源代码以登录到文件,这可能会有所帮助

  • 运行services.msc并编辑服务的属性。在“登录”选项卡上,选中“允许服务与桌面交互”

  • 使用注册表编辑器修改服务的ImagePath:转到HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\[您的服务名称]并编辑ImagePath。将
    cmd.exe/c
    追加到ImagePath字符串的开头。因此,如果原始图像路径为
    c:\myService\myService.exe
    ,则新图像路径应为
    cmd.exe/c:\myService\myService.exe

  • 开始你的服务。您应该会看到一个标题为“交互式服务检测”的弹出窗口。选择“查看信息”。您的屏幕应切换上下文并显示控制台窗口。完成后,单击“立即返回”按钮

  • 调试完成后,将ImagePath修改回其原始值。然后取消选中服务属性中的“允许服务与桌面交互”复选框,并重新启动服务


  • 警告:我只做过一次服务,它对我有效。我不知道它是否适用于任何服务,或者它是否会导致任何意外结果,因此我强烈建议您仅在非生产环境中执行此操作。

    使用Console.SetOut是一个最小的更改,它产生了足够的信息,可以确定服务或log4net下次的问题并配置目标。