带有隐藏控制台窗口的 AllocConsole()

Posted

技术标签:

【中文标题】带有隐藏控制台窗口的 AllocConsole()【英文标题】:AllocConsole() with hidden console window 【发布时间】:2017-10-03 19:19:14 【问题描述】:

我正在尝试启动以交互模式运行的 bash.exe 作为子进程。我发现这样做的唯一方法是从控制台程序启动 bash.exe,或者将 AllocConsole() 启动到非控制台程序,然后启动它。似乎如果它不是从控制台程序启动,或者至少是一个已分配控制台的程序,bash.exe 拒绝以交互模式启动。

由于基础程序必须是 GUI 程序,我必须使用 AllocConsole。但是,如果我这样做,这会创建一个可见的控制台。这对于我正在构建的程序是不可接受的。

我知道如何创建隐藏的子进程,但是弹出的控制台来自 AllocConsole,而不是 CreateProcess。有很多这样的问题,但大多数都以解决方法结束,而且似乎我的情况排除了我能找到的所有解决方法。

如何在没有控制台出现的情况下使用 AllocConsole?如果做不到这一点,如何在不使用 AllocConsole 的情况下以交互模式将 bash.exe 作为 GUI 程序的子进程启动?

【问题讨论】:

你试过用CreateProcess() using redirected STD(IN|OUT|ERR) handles启动bash吗?您实际上不需要控制台窗口即可从 GUI 应用程序与控制台应用程序进行交互。否则,请尝试在AllocConsole() 之后使用GetConsoleWindow(),然后隐藏窗口或将其移出屏幕 做一些杂耍。使用CreateProcess 通过STARTUPINFO 生成带有隐藏窗口或没有窗口(即CREATE_NO_WINDOW)的控制台进程(例如cmd.exe),通过AttachConsole 附加到它,然后终止初始控制台进程。 是的! Bash.exe 不喜欢这些管道,并且会拒绝在交互模式下运行。我只是通过将父进程运行的控制台中的控制台句柄传递给它来让它以交互模式作为子进程运行。将其隐藏或移出屏幕不会解决问题。对于全屏 GUI 应用程序来说,闪烁将是一个重大问题。我需要它永远不会出现控制台。 从服务运行它?顺便说一句,您指的是 WSL bash 还是其他类似 cygwin 或 mingw 的东西? 不要将其作为服务运行 【参考方案1】:

eryksun 的方法奏效了。我使用以下设置启动该过程。然后我可以使用带有 processId 的 AttachConsole 和 FreeConsole 来操作控制台。

siStartInfo.wShowWindow = SW_HIDE;
siStartInfo.dwFlags = STARTF_USESHOWWINDOW;

    BOOL success = CreateProcess(
        applicationAddress, // absolute path to the application
        TEXT("-i"),         // command line 
        NULL,               // process security attributes 
        NULL,               // primary thread security attributes 
        TRUE,               // handles are inherited 
        CREATE_NEW_CONSOLE,               // creation flags 
        NULL,               // use parent's environment 
        NULL,               // use parent's current directory 
        &siStartInfo,       // STARTUPINFO pointer 
        &piProcInfo);       // receives PROCESS_INFORMATION 

【讨论】:

以上是关于带有隐藏控制台窗口的 AllocConsole()的主要内容,如果未能解决你的问题,请参考以下文章

DLL 中的控制台输出窗口

使用AllocConsole在Win32程序中调用控制台调试输出

在有界面的应用程序中开启控制台调试窗口

MFC如何在有界面的应用程序中开启控制台窗口

MFC的GUI窗口使用Console输出函数printf(AllocConsole后,使用GetStdHandle取得句柄,然后就可以操作了)

从 AllocConsole C++ 获取行输入