简体   繁体   中英

AttachConsole() does not take user-input as expected

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:

  1. 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()

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM