We have an app which can run in both GUI and Console mode – so we make it as SUBSYSTEM:WINDOWS. Now, when it is invoked from Console, we want it to 'run in console mode' by 'attaching to the parent console'. For this, we are using AttachConsole() and stdin/stdout is streamed to this console. as shown in the below code:
if(AttachConsole (ATTACH_PARENT_PROCESS) == 0){
// Not launched from a console
}else{
// launched via a console
FILE * fpstdin = stdin, *fpstdout = stdout, *fpstderr = stderr;
freopen_s (&fpstdin, "CONIN$", "r", stdin);
freopen_s (&fpstdout, "CONOUT$", "w", stdout);
freopen_s (&fpstderr, "CONOUT$", "w", stderr);
}
The built application (exe) is run from cmd. When we do this, we observe few issues:
When the exe is launched from cmd, the expectation is that the exe specific user interaction (ie input / output) should continue in the same cmd terminal without the cmd prompt re-appearing in-between. However the observation is the cmd prompt reappears in-between the exe specific user interaction. Image provided below for reference: stdin issue with AttachConsole()
Running the exe shows the cmd prompt again and then the output of the application comes ie
C:\Test>MySampleApp.exe
C:\Test>This is the output from MySampleApp.exe... etc etc..
Can you tell us what we are doing wrong?
To me this works (?) (I don't know much about what I wrote in the code, I'm beginner using the Windows API, C and C++).
#include <iostream>
#include <Windows.h>
#include <tchar.h>
int APIENTRY _tWinMain(
const HINSTANCE _In_ CurrInst,
const HINSTANCE _In_opt_ PrevInst,
const PTSTR _In_ CmdLine ,
const int _In_ CmdShow ) {;
if (AttachConsole(ATTACH_PARENT_PROCESS) == 0) {
// Not launched from a console
AllocConsole();
FILE * fpstdin = stdin,
* fpstdout = stdout,
* fpstderr = stderr;
_tfreopen_s(&fpstdin, _T("CONIN$"), _T("r"), stdin);
_tfreopen_s(&fpstdout, _T("CONOUT$"), _T("w"), stdout);
_tfreopen_s(&fpstderr, _T("CONOUT$"), _T("w"), stderr);
std::cout << "Attached!\n";
std::cin.get();
} else {
// Launched from a console
AllocConsole();
FILE * fpstdin = stdin ,
* fpstdout = stdout,
* fpstderr = stderr;
_tfreopen_s(&fpstdin , _T("CONIN$" ), _T("r"), stdin );
_tfreopen_s(&fpstdout, _T("CONOUT$"), _T("w"), stdout);
_tfreopen_s(&fpstderr, _T("CONOUT$"), _T("w"), stderr);
std::cout << "Not Attached!\n";
std::cin.get();
}
FreeConsole();
}
I think it might be useful to encapsulate some of these instructions and you could use RAII on Alloc/Free Console?
Edit: And yes, i see the "duplicated code".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.