简体   繁体   English

无法获取 AllocConsole 的 STD 句柄

[英]Cannot get STD handle to AllocConsole

I've been trying to get the output handle to my console, but it doesn't seem to work.我一直在尝试获取控制台的输出句柄,但它似乎不起作用。 I got it to set the color of my text, but it's not changing.我用它来设置文本的颜色,但它没有改变。

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

I tried to debug it and I think I the handle isn't right.我试图调试它,我认为我的句柄不对。 Is there any other way to do this, and is it normal that it doesn't work?有没有其他方法可以做到这一点,它不起作用是否正常? Any fixes?任何修复?

Thanks!谢谢!

EDIT: Let me clarify, the handle that I'm trying to get is invalid.编辑:让我澄清一下,我试图获得的句柄无效。 I've no idea how to fix it.我不知道如何解决它。 I guess I'll start looking for alternatives;我想我会开始寻找替代品; maybe something is wrong with my code.也许我的代码有问题。

The standard handlers are initialized during process creation, if you call AllocConsole the new console is created far later.标准处理程序在进程创建期间初始化,如果您调用AllocConsole ,新控制台将在很晚之后创建。 AllocConsole can change the standard handles, but it's far too late for them to be used by startup code, such as the C runtime library initialization. AllocConsole可以更改标准句柄,但是对于启动代码(例如 C 运行时库初始化)使用它们来说为时已晚。

The best thing to do in this case is CreateFileW(L"CONOUT$", ...) , which gets a console handle no matter whether you are attached to parent process's console, the OS created one for you because your PE header is /SUBSYSTEM:CONSOLE , or you called AllocConsole .在这种情况下,最好的做法是CreateFileW(L"CONOUT$", ...) ,无论您是否连接到父进程的控制台,它都会获得一个控制台句柄,操作系统会为您创建一个,因为您的 PE 标头是/SUBSYSTEM:CONSOLE ,或者您调用了AllocConsole And it gets the console handle even when standard handles are redirected.即使重定向标准句柄,它也会获得控制台句柄。

And if you think you may call FreeConsole , you should be sure to close any handles returned by CreateFile first.如果您认为可以调用FreeConsole ,则应确保首先关闭CreateFile返回的所有句柄。 In the general case where the console remains active until process exit, you can let the OS close the handle for you during process cleanup.在控制台保持活动状态直到进程退出的一般情况下,您可以让操作系统在进程清理期间为您关闭句柄。

Since you specify hOut is INVALID_HANDLE_VALUE (or potentially NULL ), try calling GetLastError to find out why.由于您指定hOutINVALID_HANDLE_VALUE (或可能为NULL ),请尝试调用GetLastError以找出原因。 It is likely you don't have console session established.您可能没有建立控制台会话。

Is this a win32 Console Application or is it a Windows SubSystem application (does it have WinMain ?)这是一个 win32 控制台应用程序还是一个 Windows 子系统应用程序(它有WinMain吗?)

You could try AttachConsole(ATTACH_PARENT_PROCESS) instead of AllocConsole before GetStdHandle .您可以在GetStdHandle之前尝试AttachConsole(ATTACH_PARENT_PROCESS)而不是AllocConsole

In either case, AllocConsole and AttachConsole return a BOOL which, if FALSE , indicates you can call GetLastError to find out why.在任何一种情况下, AllocConsoleAttachConsole返回一个BOOL ,如果为FALSE ,则表示您可以调用GetLastError来找出原因。

Make sure you aren't calling hOut = GetStdHandle(STD_OUTPUT_HANDLE) followed by CloseHandle(hOut) prior to the lines listed above.确保您没有在上面列出的行之前调用hOut = GetStdHandle(STD_OUTPUT_HANDLE)CloseHandle(hOut) Unlike AllocConsole and FreeConsole , closing the std handle is not a good idea.AllocConsoleFreeConsole不同,关闭 std 句柄不是一个好主意。

Finally, try:最后,尝试:

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

So much drama for such a small thing... and by the way @Ben's answer is the proper answer is actually right.这么小的事情有这么多的戏剧性......顺便说一下@Ben的答案是正确的答案实际上是正确的。

For your problem, just do this:对于您的问题,只需执行以下操作:

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

This will allow you to get the handle of any console you have.这将允许您获得您拥有的任何控制台的句柄。 Make sure you put this after AllocConsole();确保你把它放在 AllocConsole(); 之后。

Enjoy?!享受?!

Ok so I found an answer.好的,所以我找到了答案。 Seems like a simple edit can fix it似乎一个简单的编辑可以修复它

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM