没有GUI,在运行时显示数据?

时间:2012-12-12 09:25:45

标签: c# service

当我正在处理大多数项目时,从winforms,游戏机,WPF,如果需要,我可以在运行时使用消息框或类似内容打印出我想要更容易检查的任何信息;

MessageBox.Show(whateveriwannashow);

但是,我现在正致力于Windows服务,它不允许存在任何类型的GUI。我应该向哪个方向展示一些信息? VS2010有这种内置功能吗?

4 个答案:

答案 0 :(得分:3)

System.Diagnostics.Trace是你最好的朋友。 Trace直接输出到Visual Studio的输出窗口,可以发送到记录器,也可以使用SysInternals DebugView等免费的第三方工具查看。

对于调试工作,它击败了记录。这就是原因:

  1. 它不会在您的驱动器上留下很大的日志文件。这意味着您可以精确地跟踪跟踪,而不是在磁盘上留下大文件。
  2. 如果没有任何内容正在侦听跟踪输出,那么它基本上会在以太网中丢失。
  3. 您可以使用DebugView(和没有外部依赖关系的Exe)实时观察输出
  4. 如果要记录它,只需在记录器中添加跟踪侦听器
  5. 即可
  6. 设置简单
  7. 默认情况下写入输出窗口。

答案 1 :(得分:2)

您有几个选择:

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

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

在内存日志中:允许客户端应用程序与服务进行通信并获取一些日志信息可能是一种很好的方法,但之后就没有永久记录。根据人们在服务失败的情况下多久会注意到这种方法可能不是最好的。

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

答案 2 :(得分:1)

您应该使用日志

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

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

无需修改代码。

例如,您可以使用Enterprise Librarylog4net

答案 3 :(得分: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 。在我的场景中,设置看起来像:

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

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

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

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