如何从服务 C# 捕获控制台输出?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/201616/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to capture console output from a service C#?
提问by Mike Chess
We have a C# service that is deployed to a remote customer system. The application writes a substantial amount of "diagnostic" information to the console (i.e. Console.WriteLine()). The service isn't "doing what it should." How can we capture the console output from the service in another application?
我们有一个部署到远程客户系统的 C# 服务。应用程序将大量“诊断”信息写入控制台(即 Console.WriteLine())。该服务不是“做它应该做的”。我们如何从另一个应用程序中的服务捕获控制台输出?
A WinForm version the application can be loaded at the customer location. It, unfortunately, functions correctly.
可以在客户位置加载应用程序的 WinForm 版本。不幸的是,它运行正常。
Update:
更新:
We are able to change the change the service, but would prefer not to make major changes at this time.
我们可以更改服务的更改,但目前不希望进行重大更改。
We are also logging to MSMQ, but only for "important" events. This service does interact with MSMQ for its normal operations. Or, at least, it should. The service doesn't seem to be pulling items from MSMQ when the WinForm version does. So, writing the messages that are going to the console could be problematic.
我们也记录到 MSMQ,但仅用于“重要”事件。此服务确实与 MSMQ 交互以进行其正常操作。或者,至少,它应该。当 WinForm 版本这样做时,该服务似乎不会从 MSMQ 中提取项目。因此,编写发送到控制台的消息可能会出现问题。
采纳答案by Jon Skeet
Are you able to change the service code at all? If so, using Console.SetOut to write to a file instead would be the most obvious first port of call. Then change to using a proper logging library for the next release :)
您是否能够更改服务代码在所有?如果是这样,使用 Console.SetOut 写入文件将是最明显的第一个调用端口。然后更改为在下一个版本中使用适当的日志记录库:)
回答by Patrik Svensson
I wouldn't use Console.WriteLine at all from a Window Service. You should probably log these errors to a log file.
我根本不会从窗口服务中使用 Console.WriteLine。您可能应该将这些错误记录到日志文件中。
Another way of doing this so that multiple applications can consume the logs is posting the log messages to a MSMQ queue.
执行此操作以便多个应用程序可以使用日志的另一种方法是将日志消息发布到 MSMQ 队列。
回答by Danimal
use debug.writeline and use sysinternals debugview?
使用 debug.writeline 并使用 sysinternals debugview?
回答by Michael Petrotta
You've got a bunch of options; redirecting console output to a file and using a proper logging library as mentioned are two good ones. Here's a middle option: write to the event log.
你有很多选择;如上所述,将控制台输出重定向到文件并使用适当的日志记录库是两个很好的方法。这是一个中间选项:写入事件日志。
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".
然后在应用程序事件日志(管理工具 -> 事件查看器)中查找 Source = "MyService" 的条目。
回答by Joe
In general, you should avoid writing diagnostic information directly to Console, the Event Log, MSMQ or elsewhere from your application code. Instead call a logging API, and use configuration to redirect the output wherever you want.
通常,您应该避免将诊断信息从应用程序代码直接写入控制台、事件日志、MSMQ 或其他地方。而是调用日志 API,并使用配置将输出重定向到您想要的任何位置。
For example, you could replace all the Console.WriteLine by Trace.WriteLine (*). Then you can redirect output to the console, a file or elsewhere by modifying the application configuration file: for example to output to the console, use a ConsoleTraceListener, something like:
例如,您可以将所有 Console.WriteLine 替换为 Trace.WriteLine (*)。然后,您可以通过修改应用程序配置文件将输出重定向到控制台、文件或其他地方:例如,要输出到控制台,请使用 ConsoleTraceListener,例如:
<configuration>
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<add name="configConsoleListener"
type="System.Diagnostics.ConsoleTraceListener" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
While debugging, you'll get your output on the console - on the customer site you'd configure it to redirect the trace output to a file, to the event log or similar.
在调试时,您将在控制台上获得输出 - 在客户站点上,您将其配置为将跟踪输出重定向到文件、事件日志或类似内容。
Even better, use a 3rd party logging framework (I'd recommend Log4Net) which will give you more options than System.Diagnostics.Trace.
更好的是,使用第 3 方日志记录框架(我推荐 Log4Net),它会为您提供比 System.Diagnostics.Trace 更多的选项。
(*) Trace.Write/Trace.WriteLine are the same as Debug.Write/Debug.WriteLine, except that the latter are only compiled if the DEBUG symbol is defined. So prefer Trace to Debug if you want the output to be available in Release builds.
(*) Trace.Write/Trace.WriteLine 与 Debug.Write/Debug.WriteLine 相同,只是后者仅在定义了 DEBUG 符号时才被编译。因此,如果您希望输出在发布版本中可用,则更喜欢 Trace 到 Debug。
回答by Marc
回答by Mike E
Here is how I viewed the console output of a service running under Windows 7. This might help if you are absolutely unable to modify the source code of the service to log to a file.
下面是我查看在 Windows 7 下运行的服务的控制台输出的方式。如果您绝对无法修改服务的源代码以登录到文件,这可能会有所帮助。
Run services.msc and edit the properties of the service. On the "Log On" tab, check the "Allow service to interact with desktop"
Use registry editor to modify the ImagePath of your service: Go to HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\ [your service name] and edit ImagePath. Append
cmd.exe /c
to the beginning of the ImagePath string. So if your original ImagePath isc:\myService\myservice.exe
your new ImagePath should becmd.exe /c c:\myService\myservice.exe
.Start your service. You should get a popup window titled "Interactive Services Detection". Select "View the message". Your screen should switch contexts and display the console window. When finished, click the "Return now" button.
When finished debugging, modify ImagePath back to its original value. Then uncheck the "Allow service to interact with desktop" checkbox in the service properties and restart your service.
运行 services.msc 并编辑服务的属性。在“登录”选项卡上,选中“允许服务与桌面交互”
使用注册表编辑器修改您的服务的 ImagePath:转到 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\ [您的服务名称] 并编辑 ImagePath。附加
cmd.exe /c
到 ImagePath 字符串的开头。因此,如果您的原始 ImagePath 是c:\myService\myservice.exe
您的新 ImagePath 应该是cmd.exe /c c:\myService\myservice.exe
.开始您的服务。您应该会看到一个标题为“交互式服务检测”的弹出窗口。选择“查看消息”。您的屏幕应该切换上下文并显示控制台窗口。完成后,单击“立即返回”按钮。
完成调试后,将 ImagePath 修改回其原始值。然后取消选中服务属性中的“允许服务与桌面交互”复选框并重新启动您的服务。
Warning: I've only done this with one service and it worked for me. I do not know if it will work for any service or if it will cause any unexpected results so I strongly suggest you only do this in a non-production environment.
警告:我只用一项服务完成了这项工作,它对我有用。我不知道它是否适用于任何服务,或者是否会导致任何意外结果,因此我强烈建议您仅在非生产环境中执行此操作。