Problems redirecting stdout and stderr to a GUI Component on Windows (_fileno(stdout) = -2)


I’m absolutely no Windows expert, but at the moment I’m reworking some useful classes I built in the last months for grouping them into modules and in this process I want them to be compatible to all JUCE Desktop OS targets.

For projects relying on third party libraries that make heavy use of the console for displaying errors etc. I built a Component that captures stdout and stderr via a pipe and redirects it to this component to integrate them into GUI-based applications. This works fine on Linux and Mac OS, however it doesn’t on Windows. I read a bit about GUI apps on windows not having a console by default and that there are some workarounds on creating a console for GUI apps, however this is not what I want. I’d like to have a console-less application in which third party library calls to printf, std::cerr or std::cout are redirected to my component.

According to this SO-Post, redirecting those streams via pipes should be possible, the code presented there is nearly the same to the code I currently successfully use for my Component on Unix systems. I copied the SO code to a fresh VisualStudio C++ Command Line application and saw it working too. However in my JUCE-based test-project (based on the GUI-App JUCE template) the calls to _fileno (stdout) and _fileno (stderr) both return -2 instead of the expected values 1 and 2. So it compiles but then just does nothing. I haven’t found anything on the exact meaning of this return value, however I expect a negative value to indicate some kind of error.

Now I’m asking you: Is this something that would be fixable with the project settings or some initial calls, is this something that just can’t work without a command line window on windows or are there totally different Windows-specific approaches beneath those pipes to capture stdout and stderr in this scenario on windows?

Got it fixed myself with some help from Stackoverflow. Return value -2 means that there currently is no stdout and stderr. I fixed it with allocating a console, reopening stdout and stderr and then closing it immediately via

		if (AllocConsole()) {
			freopen("CONOUT$", "w", stdout);
			freopen("CONOUT$", "w", stderr);

		ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);