1

当我处理来自winforms、控制台、WPF 的大多数项目时,如果需要,我可以打印出任何我想在运行时使用消息框等更轻松地检查的信息;

MessageBox.Show(whateveriwannashow);

但是,我现在正在开发一个 Windows 服务,它不允许存在任何类型的 GUI。我应该朝哪个方向显示一些信息?VS2010 是否具有此类东西的内置功能?

4

4 回答 4

3

System.Diagnostics.Trace是您最好的新朋友。跟踪直接输出到 Visual Studio 中的输出窗口,可以发送到记录器,也可以使用免费的第三方工具(如 SysInternals DebugView)进行查看。

对于调试工作,它胜过日志记录。原因如下:

  1. 它不会在您的驱动器上留下很大的日志文件。这意味着您可以真正细化跟踪,而不会在磁盘上留下大文件。
  2. 如果没有任何东西在监听跟踪输出,那么它基本上会丢失在以太中。
  3. 您可以使用 DebugView(和没有外部依赖的 Exe)实时查看输出
  4. 如果你想记录它,你可以简单地在你的记录器中添加一个跟踪监听器
  5. 很容易设置
  6. 它默认写入输出窗口。
于 2012-12-12T09:41:33.043 回答
2

你有几个选择:

数据库日志:服务最好写入数据库日志,您应该编写一个单独的应用程序来显示条目并帮助您理解它们。但是,这种方法可能会出现问题,因为如果数据库出现故障,您将丢失同时应该创建的任何日志条目。

文件日志:更可靠的写入,但更难以从多个位置访问。除非您打算将它们放入许多其他应用程序使用的某个中央日志文件夹中,否则很容易忘记它们所在的位置,因此通常会被忽略。

在内存日志中:允许客户端应用程序与服务通信并获取一些日志信息可能是一个好方法,但是没有永久记录。如果服务出现故障,这种方法可能不是最好的,这取决于人们多久会注意到。

最后,每种方法都有它的好处。就个人而言,我更喜欢先写入数据库,然后在数据库写入失败时级联到文件日志。内存中的日志将严格保留用于调试消息,一旦达到相当大的规模,就会清除旧条目。

于 2012-12-12T09:33:07.737 回答
1

您应该使用日志

使用抽象文本日志物理存储方式的第三方库进行日志记录如何?然后,您可以将服务配置app.config为使用任何类型的日志输出:

  • 数据库
  • 滚动平面文件
  • XML 文件
  • 窗口事件日志

无需修改您的代码。

例如,您可以使用Enterprise Librarylog4net

于 2012-12-12T09:40:38.323 回答
1

对于(半)持久性信息,我完全同意 Spencer 的观点。但是如果你需要一些快速的运行时信息来进行调试/跟踪,你可以“劫持”一个命令行窗口并写入它。

protected override OnStart(string[] args)
{
    int processId;
    IntPtr ptr = GetForegroundWindow();
    GetWindowThreadProcessId(ptr, out processId);
    var process = Process.GetProcessById(processId);

    if (String.CompareOrdinal(process.ProcessName, "cmd") == 0)
    {
        // Hijack an existing foreground cmd window.
        AttachConsole(process.Id);
    }
    else
    {
        // Or create a new one
        AllocConsole();
    }
}

protected override OnStop()
{
    FreeConsole();
}

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AllocConsole();

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool FreeConsole();

[DllImport("kernel32", SetLastError = true)]
static extern bool AttachConsole(int dwProcessId);

[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

然后,您可以使用控制台进行输出,最好使用像log4net这样的 3rd 方日志系统。在我的场景中,设置看起来像:

//Enable log4net logging into the console
ConsoleAppender appender = new ConsoleAppender {Layout = new SimpleLayout()};
BasicConfigurator.Configure(appender);

但那部分是 log4net 特定的。您应该可以使用 even Console.Write(),尽管设置起来要困难得多。

我喜欢的是,您可以将其“绑定”到服务的命令行/配置参数,如果您进行了设置,第 3 方记录器只会将日志记录从其默认位置切换到控制台。无需在代码中做任何进一步的检查。您也可以在任何地方执行此操作 - 在您的开发机器上,在远程服务器上......

无论如何,正如我一开始所说,如果你真的不需要实时信息,我会坚持 Spencer 的建议。

于 2012-12-12T09:51:30.590 回答