我有一个应用程序,我希望能够在没有参数和 GUI 的情况下运行,或者在存在参数时作为控制台应用程序运行。
int main(int argc, char *argv[])
{
if (argc > 1)
{
QCoreApplication app(argc, argv);
QTextStream out(stdout);
...
return app.exec();
}
else
{
QApplication app(argc, argv);
...
return app.exec();
}
}
这在 Linux 下工作得很好,但 Windows 不允许我做任何控制台输出。在搜索问题后,我发现了 AttachConsole() 的提示并重新打开输出,所以我添加了:
FreeConsole();
AttachConsole(ATTACH_PARENT_PROCESS);
freopen("CON", "w", stdout);
freopen("CON", "w", stderr);
freopen("CON", "r", stdin);
这工作正常,除了应用程序返回后命令行不会返回到“输入状态”。 为了澄清这一点:
C:\Users\x>
hello world
C:\Users\x>
它像这样卡住了:
C:\Users\x>
hello world
应用程序正确退出,只是 cmd 似乎不知道这一点。
那么有人可以告诉我我必须在那里进行什么样的清理吗?
最佳答案
当 shell 从交互式命令行启动控制台应用程序时,它会等待应用程序退出。这是必要的,因为它可以防止应用程序和 shell 竞争对控制台输入和输出的访问。这也意味着 shell 知道何时重新打印提示符。
当 shell 从交互式命令行启动 GUI 应用程序时,它不会等待。在这种情况下,没有必要,而且会给用户带来不方便。 (从批处理文件启动 GUI 应用程序时,它会等待。)
(用户可以使用带有或不带 /wait
选项的 start
来覆盖默认行为。)
通过使用 AttachConsole(),您已经颠覆了此机制,让您可以访问控制台,而 shell 认为没有其他东西在使用它。这会产生一个固有的竞争条件 - 您的输出可能会在 shell 提示符或用户可能运行的其他 shell 命令的输出之前、之后或混合在一起。 (此外,如果您需要用户输入,则没有可靠的方法来预测哪些输入将进入 shell,哪些输入将进入您的进程。)shell 无法检测到这种情况,甚至不会尝试这样做。
不幸的是,最重要的是,没有什么好的方法可以让单个可执行文件同时适合控制台和 GUI 使用。相反,创建两个可执行文件,每个场景一个。如果磁盘空间是一个问题,那么将其中一个可执行文件做得非常小是相当容易的,除了调用另一个可执行文件之外什么都不做。更好的是,您可以将应用程序的大部分放入一个 DLL 中,并让两个可执行文件加载它。
关于c++ - Windows GUI 以及控制台应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38920604/