If I compile this source code:
#include <stdio.h>
int main(int argc, char* args[]) {
printf("Done!\n");
return 0;
}
with gcc hello.c -o hello -mwindows
under msys2 using mingw-w64-x86_64-toolchain
toolchain, and then run it from inside msys2 I'll see:
At the same time if I call this same executable from powershell (or cmd) I'll see:
To be honest, given the -mwindows
which is saying to produce a windows executable as opposed to console one, I'm not surprised at the latter - I've seen it many times.
But how does msys2 manage to display that output?
There are very few differences between a console and GUI application on Windows and the C run-time stdio code usually does not care, it only cares about the standard Win32 handles.
The main difference is how CreateProcess
in the parent application works.
A console application gets hooked up to the parents standard Win32 handles if the parent has a console. If the parent does not have a console, a new console window is created for the application. The parent can pass optional flags to CreateProcess
to force/deny a new console.
A GUI application is not hooked up to the standard Win32 handles and no new console is created.
Powershell.exe is a real console application and it can use the default CreateProcess
handling. Because your application is not a console application it will be created without standard handles and therefore it has nowhere to write to.
The msys2 terminal application is probably not a real console application and probably calls CreateProcess
with forced handles (STARTF_USESTDHANDLES
). These handles are probably handles to pipes. Your application will see these handles as redirected stdio handles and execute in a similar fashion as how cmd.exe would perform yourconsoleapp.exe | otherconsoleapp.exe
.