【问题标题】:AttachConsole from a GUI app when the console is closed [duplicate]控制台关闭时来自 GUI 应用程序的 AttachConsole [重复]
【发布时间】:2013-02-06 01:31:45
【问题描述】:

我需要能够从我用 C++ 编写的基于 GUI 的应用程序输出到控制台,因此我选择使用 AttachConsole(ATTACH_PARENT_PROCESS) API 和 this code 来执行此操作。该方法效果很好,除了当我从命令提示符窗口启动我的 GUI 应用程序时,GUI 应用程序启动得很好,但是当我关闭命令提示符窗口时,我的 GUI 应用程序被终止(注意,不是关闭,而是终止。)有没有如何防止此应用终止?

【问题讨论】:

  • 你为什么不改用AllocConsole。这似乎更适合您的需求。 GUI 和控制台应用程序通常不能很好地混合。
  • 我不调用 AllocConsole,因为如果 GUI 应用程序自行运行(就像您通常运行它一样),我不需要分配控制台。使用该 API,命令提示符窗口打开在我的 GUI 应用旁边。
  • @Cheersandhth.-Alf:对不起,我不熟悉cat?你能提供更多细节吗?
  • @Cheersandhth.-Alf type 会是cat 的Windows 模拟
  • 据我了解,当控制台关闭时,如果你的进程附加到它上面,你的进程就会死掉。没有办法避免这种情况。 stackoverflow.com/questions/11959643/…

标签: c++ winapi console-application command-prompt


【解决方案1】:

当有人关闭控制台窗口时,您可以阻止您的应用程序关闭。

它涉及调用SetConsoleCtrlHandler 来设置拦截这些事件的HandlerRoutine。

如果您希望控制台窗口关闭,但让您的应用程序继续运行,您可以在您的HandlerRoutine 中调用FreeConsole。如果这不起作用,则处理消息以防止控制台窗口被破坏,并设置一个标志或计时器,使您的应用在从处理程序返回后调用FreeConsole。

我记得,当用户点击窗口上的 X 时,您无法阻止窗口关闭。我所做的就是修改窗口菜单。有关详细信息,请参阅http://blog.mischel.com/2008/07/14/going-too-far-back/。

【讨论】:

  • 谢谢。我尝试过这个。不幸的是,当我从处理程序调用FreeConsole 时,我的GUI 应用程序无论如何都会被终止。并且禁用关闭按钮对于我的链接来说太极端了。我的想法是仅在 printf() 或任何其他文本输出完成时将控制台附加到我的 GUI 进程,然后立即将其分离。这样它就不会保持连接状态。我似乎无法弄清楚如何优雅地分离它。有什么想法吗?
  • FreeConsole 不会优雅地分离吗?
  • 这一切都在我在 cmets 中链接到这个 Q 的 Q 中涵盖了。
  • @DavidHeffernan:是的,你是对的。直到我发帖后我才看到你的评论。我的错。
  • @JimMischel:不,FreeConsole 本身不会涵盖它。如果您查看我在原始问题中发布的示例代码,他们会对 C 类型句柄、stdout、stdin、stderr 等进行大量调整。所以我假设所有必须恢复的内容和文件描述符关闭。所以如果你做了所有这些然后打电话给FreeConsole 我的attaching-only-when-you-need-it 方法实际上效果很好。唯一的缺点是我不能使用标准的printf 或cout 类型的方法,需要自己编写。但这基本上是源代码的“查找和替换”工作......
【解决方案2】:

我能够通过在将文本发布到stdout 流之前附加到父控制台然后从它分离来解决此问题。这样,文本就可以正常发布,并且控制台与我的 GUI 应用程序保持分离。

Here's the MFC/C++ class 为想要使用它的人提供完整的实现。

【讨论】:

  • 请考虑您可以通过键入所有 5 个字符而不是所有源代码等来做到这一点,正如我最初在评论中向您解释的那样,并在您询问时进一步解释,并用说明完整的示例源代码,构建示例并在答案中运行示例,由于响应,我删除了
  • 您冒着在您的 GUI 进程附加到控制台时将关闭控制台的风险。
  • @Cheersandhth.-Alf 我回来看看这个。当控制台关闭时,它会关闭cat 进程,但会离开其他 GUI 子系统进程。因为cat 进程是附加到控制台的进程。这很整洁。我认为,如果您只解释这一点,您的回答会很受欢迎。但是,我非常怀疑 ahmd0 是否希望始终通过管道输出。更重要的是,这样做会锁定控制台。我再次确定 ahmd0 不想要。 FWIW,在我看来,ahmd0 不应尝试将 GUI 子系统应用程序连接到现有控制台。它会导致疼痛。
  • @DavidHeffernan:是的,我遇到了问题。不是您所描述的,但主要是当有人使用 VBScript 和 ASP(经典)尝试从我的应用程序中读取 stdout 或获取 Exec.Status 时,输出什么都没有,或者他们的状态为 0。太糟糕了,GUI 应用程序对控制台进程如此糟糕......
  • 一种解决方案可能是拥有一个单独的控制台进程,该进程使用命名管道或任何其他 IPC 方式简单地将所有输入/输出通过管道传输到 GUI 应用程序。这是 a** 编码的一个更大的痛苦,但似乎 MS 解决方案并没有真正简单的修复......
猜你喜欢
  • 2012-03-09
  • 2014-02-25
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 1970-01-01
  • 2018-05-22
  • 2013-11-24
  • 1970-01-01
相关资源
最近更新 更多