【问题标题】:How to know whether we are in a console or a windowed app?如何知道我们是在控制台还是窗口应用程序中?
【发布时间】:2010-10-01 15:11:43
【问题描述】:

上下文:编写 c/c++ win32-mfc 库

如何知道我们是在控制台还是窗口应用程序中?

【问题讨论】:

  • 如果这是一个图书馆,你为什么需要知道?
  • 图书馆不应该担心它在哪里使用。应用程序应该担心。这是理想主义的观点,也有例外。但我会说该规则的例外情况很少见:)
  • 存在异常以将错误传达给调用库的代码;)

标签: c++ windows winapi console


【解决方案1】:

对此我不确定(我自己没有尝试过),但您可以调用 GetStartupInfo 函数来完成一个 STARTUPINFO 结构。

也许控制台和 Windows 应用程序设置 dwFlags 成员的 STARTF_USESHOWWINDOW 标志不同,您可以这样区分它们。

正如您问题的 cmets 中所提到的,当库需要知道这些事情时,这通常不是一个好兆头 - 您可以保持它越解耦越好。

希望对您有所帮助。

【讨论】:

  • 对 STARTF_USESHOWWINDOW 的测试是不可靠的,除非您自己控制启动控制台应用程序。使用 CREATE_NEW_WINDOW、STARTF_USESHOWWINDOW 和 SW_HIDE 创建进程是完全有效的。
【解决方案2】:

您可以通过调用win32函数GetConsoleWindow来确定当前是否有控制台连接到进程。如果它返回 NULL 则没有控制台附加到该进程。但是,这不一定会告诉您是否在窗口应用程序中运行。例如,我可以有一个窗口应用程序,它在启动时使用AllocConsole 来分配一个用于调试输出的控制台,在这种情况下,您将同时拥有两者。我可以看到您描述的另一个问题是应用程序可能没有窗口并且没有附加控制台(例如 Windows 服务)。

我也必须同意 litb 和 Martin 的观点。如果您的库需要知道这一点,那么它可能还不够解耦。例如,如果您使用它来确定将调试输出发送到哪里,最好的方法是使用 cout 或 cerr,让使用该库的应用程序处理将流重定向到它想要的位置。

【讨论】:

  • 好的,所以问题是“bad-conditionned”;基于 GetConsoleWindow 的近似方法是使用 EnumThreadWindows 来测试每个窗口是否是控制台窗口,并将其 hwnd 与通过 GetConsoleWindow 获得的进行比较。
  • 如果进程以CREATE_NO_WINDOW 标志启动,GetConsoleWindow 将不起作用——这正是 Qt 通常启动进程的方式。使用该标志,您将拥有不可见的控制台:文件 CONOUT$CONIN$ 存在(并且工作),AllocConsole()/AttachConsole() 失败,GetConsoleCP 返回非零值等;但是GetConsoleWindow() 返回NULL,因为没有控制台窗口。所以为了测试是否有一个附加的控制台,!!GetConsoleCP() 工作得更可靠:巧合的是,这就是 Cygwin 使用的。
猜你喜欢
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 2011-10-18
  • 2014-09-17
  • 1970-01-01
相关资源
最近更新 更多