【问题标题】:how to use the eventual lauching console in a winmain application?如何在 winmain 应用程序中使用最终的启动控制台?
【发布时间】:2018-04-19 11:38:50
【问题描述】:

我有一个小的 winmain 应用程序。 这是一个 winmain,因为我不希望它在启动时闪烁控制台。 但是如果它是从控制台启动的,我想在这个控制台中打印。

这可能吗?

【问题讨论】:

  • 是的,通过AttachConsole,但是如果你通过AllocConsole分配一个新的会更好。启动您的程序的控制台应用程序可能不会等待您的进程退出,因此如果您附加到它的控制台并打印,那么您可能会将文本注入到用户输入的中间或与它的输出混合。
  • 我只会在我的应用程序启动时打印。所以我并不担心这个控制台被同时使用。我如何找到这个控制台来连接它?谢谢。
  • 它是AttachConsole(ATTACH_PARENT_PROCESS),就像documented
  • 实际上 attachconsole 工作,但它没有在其中打印。我也会尝试附加标准输出。
  • 在调用AttachConsole 之前,调用SetStdHandle 将所有3 个标准句柄设置为NULL。这确保它们将使用控制台的句柄值进行更新。对于 CRT,您必须关闭文件描述符 0、1、2 并按标准输入、输出和错误的顺序在每个标准句柄上调用 _open_osfhandle。如果你想要FILE 流,你可以使用_fdopen。或者,如果您想使用stdinstdoutstderr 流(例如wprintf),请使用特殊的“CONIN$”和“CONOUT$”设备文件调用freopen,而不是调用_open_osfhandle 在标准手柄上。

标签: user-interface winapi console winmain


【解决方案1】:

这是我保留的解决方案:

if ( AttachConsole(ATTACH_PARENT_PROCESS) )
{
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    int fd = _open_osfhandle((intptr_t)hStdOut, _O_TEXT);
    if (fd > 0) *stdout = *_fdopen(fd, "w");
}

【讨论】:

  • 分配给*stdout 是不可移植的,而且我认为它甚至不适用于使用 C++ 对象的新通用 CRT。
【解决方案2】:

正如 eryksun 在 cmets 中指出的,AttachConsole 并不完美,因为 cmd.exe 只等待控制台应用程序。

一个偷偷摸摸的解决方法是有一个小控制台帮助程序 .exe,您将其重命名为 .com。它位于您和父控制台应用程序之间。您仍然需要使用 AttachConsoleDuplicateHandle 来访问 GUI 应用程序中的控制台句柄...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    相关资源
    最近更新 更多