【问题标题】:Cannot get STD handle to AllocConsole无法获取 AllocConsole 的 STD 句柄
【发布时间】:2017-08-22 16:28:23
【问题描述】:

我一直在尝试获取控制台的输出句柄,但它似乎不起作用。我得到它来设置我的文本的颜色,但它没有改变。

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hOut, 0x0A)

我尝试调试它,但我认为我的句柄不对。有没有其他方法可以做到这一点,它不起作用是否正常?有什么修复吗?

谢谢!

编辑:让我澄清一下,我试图获取的句柄是无效的。我不知道如何解决它。我想我会开始寻找替代品;也许我的代码有问题。

【问题讨论】:

  • 我认为那不适合我? @GraemeWicksted
  • 其他人发表了评论,这是对该评论的回应,随后被作者删除。

标签: c++ windows-console


【解决方案1】:

标准处理程序在进程创建过程中被初始化,如果你调用AllocConsole,新的控制台会在很久以后创建。 AllocConsole 可以更改标准句柄,但是对于启动代码(例如 C 运行时库初始化)使用它们已经太晚了。

在这种情况下最好的做法是CreateFileW(L"CONOUT$", ...),无论您是否附加到父进程的控制台,操作系统都会为您创建一个控制台句柄,因为您的PE头是/SUBSYSTEM:CONSOLE,或者您调用AllocConsole。即使标准句柄被重定向,它也会获得控制台句柄。

如果您认为可以调用FreeConsole,则应确保首先关闭CreateFile 返回的所有句柄。在一般情况下控制台在进程退出之前保持活动状态,您可以让操作系统在进程清理期间为您关闭句柄。

【讨论】:

  • @AxIoN: freopen_s 作用于FILE*,它不会为您提供需要传递给SetConsoleTextAttributeHANDLE。我的答案不是如何修复 GetStdHandle,而是如何让控制台 100% 可靠地处理。
  • @eryksun:这是官方记录的,还是只是观察到的可能特定于版本的行为?啊,我在GetStdHandle 看到它
【解决方案2】:

由于您指定hOutINVALID_HANDLE_VALUE(或可能是NULL),请尝试调用GetLastError 找出原因。您可能没有建立控制台会话。

这是一个 win32 控制台应用程序还是一个 Windows 子系统应用程序(是否有 WinMain?)

您可以在GetStdHandle 之前尝试AttachConsole(ATTACH_PARENT_PROCESS) 而不是AllocConsole

在任何一种情况下,AllocConsoleAttachConsole 都会返回一个 BOOL,如果是 FALSE,则表明您可以调用 GetLastError 找出原因。

确保您没有在上面列出的行之前调用hOut = GetStdHandle(STD_OUTPUT_HANDLE) 后跟CloseHandle(hOut)。与AllocConsoleFreeConsole 不同,关闭std 句柄不是一个好主意。

最后,试试:

#define _WIN32_WINNT 0x0501#include <windows.h> 之前

【讨论】:

  • 它有一个不同的名称,但我想在发布时将其更改为 just out,但我有一个错字(两次)。我确实提到了句柄是无效的,虽然我不知道如何修复它
【解决方案3】:

这么小的事情有这么多戏剧性......顺便说一下@Ben的答案是正确的答案实际上是正确的。

对于您的问题,只需这样做:

freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);

这将允许您获得您拥有的任何控制台的句柄。确保将其放在 AllocConsole();

之后

享受吗?!

【讨论】:

  • 我遇到了类似的问题,这解决了。我把这段代码放在 AllocConsole 之后 GetStdHandle 之前。
【解决方案4】:

好的,我找到了答案。似乎一个简单的编辑就可以解决它

#define setcsattr(clr) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), clr)

【讨论】:

  • 这与问题中的代码相同——只是在一个宏中,没有中间 HANDLE 变量。
  • 是的,这似乎是问题所在。
  • 出了什么问题?我看不出有什么实际区别。
  • 句柄初始化不正确。我的修复只是一个快速修复
  • 如果句柄值本身不好,这个宏不会做任何修复它。这没有任何意义作为答案。但我没有投反对票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
  • 1970-01-01
  • 2017-08-17
  • 1970-01-01
  • 2018-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多