简体   繁体   English

AttachConsole() 未按预期接受用户输入

[英]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.我们有一个可以在 GUI 和控制台模式下运行的应用程序 - 所以我们将其设置为 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.为此,我们使用 AttachConsole() 并将 stdin/stdout 流式传输到此控制台。 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.构建的应用程序 (exe) 从 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.当从 cmd 启动 exe 时,期望 exe 特定的用户交互(即输入/输出)应在同一 cmd 终端中继续,而不会在两者之间重新出现 cmd 提示。 However the observation is the cmd prompt reappears in-between the exe specific user interaction.然而观察是 cmd 提示重新出现在 exe 特定用户交互之间。 Image provided below for reference: stdin issue with AttachConsole()下面提供的图片供参考: AttachConsole() 的标准输入问题

  2. Running the exe shows the cmd prompt again and then the output of the application comes ie运行exe再次显示cmd提示然后应用程序的output来了即

    C:\Test>MySampleApp.exe C:\Test>MySampleApp.exe

    C:\Test>This is the output from MySampleApp.exe... etc etc.. C:\Test>这是来自 MySampleApp.exe 的 output... 等等。

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++).对我来说,这很有效(?)(我不太了解我在代码中写的内容,我是使用 Windows API、C 和 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?我认为封装其中一些指令可能很有用,您可以在 Alloc/Free 控制台上使用 RAII?

Edit: And yes, i see the "duplicated code".编辑:是的,我看到了“重复代码”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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