操作系统是 Windows 10。
应用程序与 /SUBSYSTEM:WINDOWS 链接,并带有附加/分配的控制台,并且输入/输出流重定向如下:
void InitConsole()
{
if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()) {
SetConsoleOutputCP(CP_UTF8);
FILE* dummy;
freopen_s(&dummy, "CONIN$", "r", stdin);
freopen_s(&dummy, "CONOUT$", "w", stdout);
freopen_s(&dummy, "CONOUT$", "w", stderr);
DWORD consoleMode;
GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &consoleMode);
consoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), consoleMode);
std::ios::sync_with_stdio(true);
std::wcout.clear();
std::cout.clear();
std::wcerr.clear();
std::cerr.clear();
std::wcin.clear();
std::cin.clear();
}
}
这是可行的,文本以颜色等方式显示,但是在程序退出后,控制台提示符会覆盖记录的文本,而不是从结束的地方继续:
这种情况发生在 Windows Terminal、PowerShell 和 Command Prompt,以及 VSCode 集成终端上。
使用 fmtlib 记录文本。然而
std::cout
和 printf()
的行为同样是错误的。
有没有办法将此行为纠正为更熟悉的控制台提示符,在使用 /SUBSYSTEM:WINDOWS 时从记录的文本结束处继续?像这样:
通过使用 /SUBSYSTEM:CONSOLE 实现预期行为,而不调用
InitConsole()
函数。
最小可重现示例:(与 /SUBSYSTEM:WINDOWS 链接)
#define UNICODE
#define _UNICODE
#include <iostream>
#include <windows.h>
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()) {
SetConsoleOutputCP(CP_UTF8);
FILE* dummy;
freopen_s(&dummy, "CONIN$", "r", stdin);
freopen_s(&dummy, "CONOUT$", "w", stdout);
freopen_s(&dummy, "CONOUT$", "w", stderr);
DWORD consoleMode;
GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &consoleMode);
consoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), consoleMode);
std::ios::sync_with_stdio(true);
std::wcout.clear();
std::cout.clear();
std::wcerr.clear();
std::cerr.clear();
std::wcin.clear();
std::cin.clear();
}
std::cout << "Test Text 1\n";
std::cout << "Test Text 2\n";
std::cout << "Test Text 3\n";
FreeConsole();
return 0;
}
当编译为 Windows 程序时,它会异步启动(可以说是在后台),并且命令提示符会立即出现。它不会等待程序完成。
如果您不希望在程序完成之前出现命令提示符,我建议将其编译为控制台程序。