Allocconsole() Not Displaying Cout

AllocConsole() not displaying cout

I vaguely recall that you might need to redirect the stdout to the console. I might be wrong though (since you had your code working earlier):

AllocConsole();
freopen("CONOUT$", "w", stdout);
std::cout << "This works" << std::endl;

Unable to write to AllocConsole()

After allocating a new console via AllocConsole(), you need to re-open the standard streams (stdout, stderr, stdin) before you can use them.

You can do so by using freopen (in newer versions of Visual Studio you need to use freopen_s)
Example:

FILE *fDummy;
freopen_s(&fDummy, "CONIN$", "r", stdin);
freopen_s(&fDummy, "CONOUT$", "w", stderr);
freopen_s(&fDummy, "CONOUT$", "w", stdout);

If you want to use the deprecated freopen you can disable the warning by #defineing _CRT_SECURE_NO_WARNINGS.

If you also want to use the wide-character streams (std::wcout, std::wcerr, etc...), you need to call SetStdHandle() to set a new output handle for your process. You can get the required file handle for this by calling CreateFile() with CONOUT$ / CONIN$ as file name:

HANDLE hConOut = CreateFile(_T("CONOUT$"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
SetStdHandle(STD_OUTPUT_HANDLE, hConOut);

Additionally, if you tried to use one of the streams before re-opening them, they will have the std::ios_base::badbit and std::ios_base::failbit
set in their iostate, so subsequent writes / reads will be ignored.

You can reset the stream state with .clear(), after which you can read/write from/to the stream again:

std::cout.clear();
std::cin.clear();

Heres a full example of re-opening all the streams after AllocConsole():

void CreateConsole()
{
if (!AllocConsole()) {
// Add some error handling here.
// You can call GetLastError() to get more info about the error.
return;
}

// std::cout, std::clog, std::cerr, std::cin
FILE* fDummy;
freopen_s(&fDummy, "CONOUT$", "w", stdout);
freopen_s(&fDummy, "CONOUT$", "w", stderr);
freopen_s(&fDummy, "CONIN$", "r", stdin);
std::cout.clear();
std::clog.clear();
std::cerr.clear();
std::cin.clear();

// std::wcout, std::wclog, std::wcerr, std::wcin
HANDLE hConOut = CreateFile(_T("CONOUT$"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hConIn = CreateFile(_T("CONIN$"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
SetStdHandle(STD_OUTPUT_HANDLE, hConOut);
SetStdHandle(STD_ERROR_HANDLE, hConOut);
SetStdHandle(STD_INPUT_HANDLE, hConIn);
std::wcout.clear();
std::wclog.clear();
std::wcerr.clear();
std::wcin.clear();
}

AllocConsole not printing when in Visual Studio

I got the same issue. Turns out writing to the console works in visual studio only when debugging in hosted process. Go to Project Properties -> Debug -> Enable Debuggers and make sure 'Enable Visual Studio hosting process' is checked.

Doing a std::endl before AllocConsole causes no display of std::cout

Before you call RedirectIOToConsole() there is nothing for cout to output onto. Since cout is buffered, the output is stored in a buffer until a flush is performed. endl contains a flush.

When you try to flush the output with no console available, the cout stream sets the badbit in the iostate.

When you then do the next step of cout << "My Trace 2" << endl; the output is not proceeding because before actually writing the data to the output file (stdout), cout checks the iostate and says "Oh, this is not good, we have badbit set" and bails out without trying to write.

You could, in theory, fix this by calling cout.clear();, but I would suggest that it's a better plan to not call cout before you have allocated a console - it serves no purpose to output things before you have something to output to.

Console showing when running winapi program

When you link a Windows executable, you have the option of determining a flag in the PE header that determines whether or not the executable represents a console application or a Windows application. The only thing this flag does is determine whether Windows creates a console for your program when you start it (and possibly also connect the standard handles to it; I don't know for sure, but the AllocConsole() docs imply so). Typical Windows programs don't use a console, so this is a good thing for them.

I don't know what project templates Code::Blocks provides by default, but Visual Studio provides both console application and Windows application templates, and which one you choose determines what this linker flag is set to. You should be able to change the flag with either IDE in its project preferences page. (The different project templates mainly give you different starting code and settings to work from, but they're by no means absolute measures of what you can write.)

If you used Code::Blocks without making a project (somehow; I don't use Code::Blocks) it's important to know that MinGW, which is likely to be the compiler that Code::Blocks comes with, produces console applications by default.

As Jonathan Potter's comment above explained, there's nothing special about the console; you can create consoles and use them on the fly in your program. See MSDN for details. If you do this, however, see Remy Lebeau's comment below as you need to tell stdio (and iostream, in the case of C++) about it. Likewise, a console program is free to create regular windows as it so chooses.

The last pitfall is that Microsoft's compiler actually distinguishes between main) for console applications and WinMain() for Windows applications. WinMain() was introduced because 16-bit Windows needed extra information at startup: the hPrevInstance and lpCmdLine arguments are deprecated, and the hInstance and nCmdShow arguments can be accessed through a variety of other means. That being said, I don't know how to get Microsoft's compilers to accept main() on a Windows application project and vice versa; you could probably get somewhere with some searching...

Also be careful when you refer to the components of Visual Studio: Visual C++ and Visual Basic are very different things.

Console.Out Output is showing in Output Window, Needed in AllocConsole()

AllocConsole() does not work on it's own, because VS 2017 does some "debug stdout redirect magic". To fix this you need to create a console with AllocConsole() and fix the stdout handle.

Here is the snipped I found:

[DllImport("kernel32.dll",
EntryPoint = "AllocConsole",
SetLastError = true,
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern int AllocConsole();

[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
uint lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
uint hTemplateFile);

private const int MY_CODE_PAGE = 437;
private const uint GENERIC_WRITE = 0x40000000;
private const uint FILE_SHARE_WRITE = 0x2;
private const uint OPEN_EXISTING = 0x3;

public static void CreateConsole()
{
AllocConsole();

IntPtr stdHandle = CreateFile(
"CONOUT$",
GENERIC_WRITE,
FILE_SHARE_WRITE,
0, OPEN_EXISTING, 0, 0
);

SafeFileHandle safeFileHandle = new SafeFileHandle(stdHandle, true);
FileStream fileStream = new FileStream(safeFileHandle, FileAccess.Write);
Encoding encoding = System.Text.Encoding.GetEncoding(MY_CODE_PAGE);
StreamWriter standardOutput = new StreamWriter(fileStream, encoding);
standardOutput.AutoFlush = true;
Console.SetOut(standardOutput);

Console.Write("This will show up in the Console window.");
}

Special thanks to Ramkumar Ramesh for the work-around:
Console Output is gone in VS2017

No console output when using AllocConsole and target architecture x86

When "Enable native code debugging" is enabled, output from consoles crated with AllocConsole is redirected to the debug output window instead.

The reason this only happens in x86 and not AnyCPU is because you can only debug native code in an x86 application.

Note that this behavior only occurs with consoles created with AllocConsole. A console application's output is not redirected.

EDIT: The other reason for the console not outputting text is when you've written to the console before calling AllocConsole.

Regardless of the reason, this code will restore output if it was redirected, and reopen the console in case it's invalid. It uses the magic number 7 which is what the handle of stdout usually equals to.

using System;
using System.IO;
using System.Runtime.InteropServices;

public static class ConsoleHelper
{
public static void CreateConsole()
{
AllocConsole();

// stdout's handle seems to always be equal to 7
IntPtr defaultStdout = new IntPtr(7);
IntPtr currentStdout = GetStdHandle(StdOutputHandle);

if (currentStdout != defaultStdout)
// reset stdout
SetStdHandle(StdOutputHandle, defaultStdout);

// reopen stdout
TextWriter writer = new StreamWriter(Console.OpenStandardOutput())
{ AutoFlush = true };
Console.SetOut(writer);
}

// P/Invoke required:
private const UInt32 StdOutputHandle = 0xFFFFFFF5;
[DllImport("kernel32.dll")]
private static extern IntPtr GetStdHandle(UInt32 nStdHandle);
[DllImport("kernel32.dll")]
private static extern void SetStdHandle(UInt32 nStdHandle, IntPtr handle);
[DllImport("kernel32")]
static extern bool AllocConsole();
}

See How to detect if Console.In (stdin) has been redirected? for another way to detect if the console handles have been redirected.

PostMessage Not working with allocated console in winform app

Try sending a WM_SYSCOMMAND message with wParam = SC_CLOSE. This more closely mimics selecting 'Close' from the system menu.



Related Topics



Leave a reply



Submit