I'd like to have a windows application with the following behaviour:
1. if it is started from an existing command line window (cmd.exe) then it writes its stdout to that console.
2. If it is started by double clicking its icon, it doesn't open a new console and doesn't write its stdout anywhere.
To achieve just 1, I can set the /SUBSYSTEM
linker argument to CONSOLE
but then if I double click the app icon, a new console window is opened.
To achieve 2, I set the same argument to WINDOWS
, but then if I start the app from the console, its stdout is not directed to the console.
I want the same executable to have both behaviors.
So far what I found is that I can create a /SUBSYSTEM:WINDOWS
executable and do this:
DWORD ret = AttachConsole(ATTACH_PARENT_PROCESS)
if (ret != 0) { // succeeds only if the parent is cmd.exe
HANDLE outh = GetStdHandle(STD_OUTPUT_HANDLE);
WriteFile(outh, "Hello", 5, NULL, NULL);
}
This writes Hello
to the console if the process was started from one and does nothing otherwise.
Now there is just the problem of getting the CRT to take outh
as the HANDLE for stdout. How can I do that?
Another problem with this option is that the cmd.exe is not blocking on the started process. Once the new process is started, cmd.exe just goes back to the prompt and the Hello
string appears right there at the prompt. If the user presses Enter on the console, another prompt appears. Any idea on how to prevent that?
Found out the answer here: http://dslweb.nwnexus.com/~ast/dload/guicon.htm
DWORD ret = AttachConsole(-1);
if (ret != 0) {
HANDLE lStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
int hConHandle = _open_osfhandle((intptr_t)lStdHandle, 0);
FILE* fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
}
And as for making cmd.exe wait, that doesn't seem possible: http://blogs.msdn.com/b/oldnewthing/archive/2009/01/01/9259142.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With