【发布时间】:2017-11-12 22:19:43
【问题描述】:
我最近将我的一台电脑从 windows 7 pro 升级到 windows 10 pro。我正在尝试运行一些我知道正在另一台 Windows 10 机器上运行的代码(从一开始就是 win10 pro)。在这两种情况下,我都使用 Visual Studio Community 2017,目标平台是 Windows 10,平台工具集是 v141。我尝试了几个不同的 Windows SDK 版本,但并没有改变结果。调试和发布模式构建的行为方式相同。该应用程序是从 Visual Studio 运行的,具有通常的“无需调试即可启动”。从外部控制台运行到 Visual Studio 没有任何区别。
这几乎是 MS 提供的用于在终端应用程序中启用 ANSI 颜色模式的示例代码:
#include <Windows.h>
#include <iostream>
int main()
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD consoleMode;
GetConsoleMode(hConsole, &consoleMode);
consoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(hConsole, consoleMode))
{
auto e = GetLastError();
std::cout << "error " << e << "\n";
}
else
std::cout << "\x1b[32mgreen\n";
}
在升级后的机器上,SetConsoleMode 返回 false,GetLastError 返回 87(“参数不正确”),后续输出中控制台不处理 ANSI 颜色代码。在另一台机器上,这一切都成功了,并且按预期呈现了 ansi 颜色。
在升级后的机器上打开控制台窗口显示版本 10.0.10240,在另一台机器上显示版本 10.0.14393。虽然我有点惊讶升级后的机器没有运行更新的版本,但它运行的版本应该支持 ANSI 颜色。
什么可以解释两台机器之间的行为差异?
【问题讨论】:
-
您需要在调用
SetConsoleMode失败后立即调用GetLastError。您的代码之间有很多 C++ 代码,并且不能安全地假设错误代码确实是您声明的错误代码。反正ENABLE_VIRTUAL_TERMINAL_PROCESSING只能用,“如果 hConsoleHandle 参数是屏幕缓冲区句柄”。 -
这与
SetConsoleMode意外失败的事实没有区别,并且在两台机器上运行的相同代码应该显示相同的行为并没有显示任何这样的东西。我对代码进行了简单的编辑,错误代码完全相同,这不足为奇。 -
不同的是,我们不知道错误模式的细节。它可能是错误代码 87,或者完全是其他东西。当有人指出明显的混乱来源时,无需大惊小怪。
-
即使根本没有调用
GetLastError,相同的代码,在相同的操作系统上以相同的方式构建和运行,在两者上的行为方式应该相同。为什么在一台机器上运行它会提供屏幕缓冲区句柄,而在另一台机器上运行却不提供?
标签: visual-studio winapi windows-console