4

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.

2
  • I figure that wasn't for me? @GraemeWicksted Commented Aug 22, 2017 at 16:55
  • someone else had commented and it was in response to that comment which was subsequently removed by the author. Commented Aug 23, 2017 at 15:29

4 Answers 4

5

The standard handlers are initialized during process creation, if you call AllocConsole the new console is created far later. 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.

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. 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. 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.

Sign up to request clarification or add additional context in comments.

2 Comments

@AxIoN: freopen_s acts on a FILE*, it doesn't give you a HANDLE that you need to pass to SetConsoleTextAttribute. My answer is not how to fix GetStdHandle, but rather how to get a console handle 100% reliably.
@eryksun: Is this documented officially, or just observed behavior which might be version specific? Ahh, I see it here in GetStdHandle
1

Since you specify hOut is INVALID_HANDLE_VALUE (or potentially NULL), try calling GetLastError to find out why. 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?)

You could try AttachConsole(ATTACH_PARENT_PROCESS) instead of AllocConsole before GetStdHandle.

In either case, AllocConsole and AttachConsole return a BOOL which, if FALSE, indicates you can call GetLastError to find out why.

Make sure you aren't calling hOut = GetStdHandle(STD_OUTPUT_HANDLE) followed by CloseHandle(hOut) prior to the lines listed above. Unlike AllocConsole and FreeConsole, closing the std handle is not a good idea.

Finally, try:

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

1 Comment

It has a different name but I wanted to change it into just out when posting and I had a typo (twice). And I did mention that the handle was invalid, though I've no idea how to fix it
0

So much drama for such a small thing... and by the way @Ben's answer is the proper answer is actually right.

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();

Enjoy?!

1 Comment

I was having a similar issue and this solved it. I put this code after AllocConsole but before GetStdHandle.
-1

Ok so I found an answer. Seems like a simple edit can fix it

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

6 Comments

This is the same code as in the question -- just in a macro and without an intermediate HANDLE variable.
Yes, it seems that that was the problem.
What was the problem? I don't see any practical difference.
The initialization of the handle was not right. my fix was just a fast fix
If the handle value itself is bad, this macro doesn't do anything to fix it. This makes no sense as an answer. But I didn't downvote it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.