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

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

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

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

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

  1. 继续创建调用者控制的更通用的日志记录入口点/旋钮。
  2. 创建一个单独的入口点/旋钮,自动为您想要自动支持的案例设置通用入口点/旋钮。

尽管如此,根据您的描述,这似乎太复杂了。 您是否考虑在诊断集合中使用适当的TraceListener,其中控制台应用程序添加适当的TraceListener以输出到控制台,非控制台应用程序添加相应的EventLog TraceListener以输出到Windows事件日志? 这具有与所有内置.net日志记录支持一起工作的附加优势,而不假设任何外部依赖性(例如,log4net)。

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

但仍然是一个黑客。

以前曾问过这个问题的变种。 就是这里和这里 。

‘解决方案似乎归结为两种选择

  • 用reflection来弄清楚你在叫什么。
  • 在控制台应用程序的情况下,在try-catch块中调用console,看看它是否失败或成功。

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

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

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

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

我知道这是一种黑客攻击,但是当没有控制台时,调用Console.Read会抛出exception。

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

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