如何检测我是否在控制台中运行

时间:2009-04-13 17:32:43

标签: c# .net vb.net logging

是否有一种简单的方法可以让代码库自动检测是否从控制台应用程序或Windows应用程序调用它?我希望我的库不报告Windows事件日志,如果它是从控制台窗口调用,而是报告给控制台窗口。但是,如果它不在控制台窗口中运行,则应报告给Windows事件日志。

我考虑过要求我的日志记录组件被传递给日志目标,但如果它本身可以自动处理这两个目标那么它会很简洁。我还没有需要像log4net这样广泛的东西,事实上,如果有必要提供支持来记录数据库/文件和其他未知的日志记录目标,那么我可能会推荐这样的解决方案。现在,只是让我的组件自动检测环境并根据环境登录到控制台或事件日志就足够了。

4 个答案:

答案 0 :(得分:8)

在架构上,将日志记录上下文传递到库组件是正确的选择。图书馆没有,实际上也不应该知道它正在运行的环境的大量背景。

因为您希望在库中本地支持这两个特殊情况,我建议采用统一的方法。

  1. 继续创建调用者控制的更通用的日志记录入口点/旋钮。
  2. 创建一个单独的入口点/旋钮,自动为您想要自动支持的案例设置广义入口点/旋钮。
  3. 尽管如此,根据你的描述,这似乎太复杂了。您是否考虑过在诊断集合中使用适当的TraceListener,其中控制台应用程序添加适当的TraceListener以输出到控制台,非控制台应用程序添加相应的EventLog TraceListener以输出到Windows事件日志?这具有与所有内置.net日志记录支持一起工作的附加优势,而不会假设任何外部依赖性(例如,log4net)。

答案 1 :(得分:7)

刚刚发现“Console.Title”将是Windows应用程序中的空白字符串,它将自动在控制台应用程序中设置。

但仍然是一个黑客。

答案 2 :(得分:1)

之前已经问过这个问题的变种。即herehere

” 解决方案似乎归结为两个选项

  • 用反射来弄清楚是什么 打电话给你。
  • 在控制台应用程序的情况下 在try-catch中调用console 阻止并查看它是否失败或 成功。

我自己的建议是让你的图书馆导出一个界面。该接口具有返回调用者类型的函数或属性。调用对象有一个实现接口的类,并返回它的类型。因为复杂性是一个问题,你可以通过你在界面中的位置来控制它。

如果应用程序没有在库中注册,那么您可以尝试抛出错误或尝试一些自动检测方案。

通过使用接口并抛出错误,您可以使用库向程序员明确指出您期望的内容。两者之间的相互作用由界面定义。

此外,交互比自动方案更灵活,因为作为用户,我可以选择我的调用二进制文件如何与您的库交互而不是一些神秘的规则。

答案 3 :(得分:1)

我知道这是一种黑客行为,但是当没有控制台时,调用Console.Read会抛出异常。

bool isConsole = true;
try
{
    isconsole = Console.CursorLeft >= int.MinValue;
}
catch( IOException )
{
    // Try to attach to parent process's console window
    isConsole = AttachConsole( 0xFFFFFFFF );
}   

...

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

这是副作用,因此它可能不是一种可靠的检测方法,但它现在可以使用。