在 Windows 下启用 ANSI 颜色时 SetConsoleMode 返回 false 10

SetConsoleMode returning false when enabling ANSI color under Windows 10

我最近将我的一台电脑从 windows 7 pro 升级到 windows 10 pro。我正在尝试 运行 一些我知道在另一台 windows 10 机器(从一开始就是 win10 pro)上运行的代码。在这两种情况下,我都使用 Visual Studio Community 2017,目标平台是 Windows 10,平台工具集是 v141。我尝试了几个不同的 windows SDK 版本,结果没有改变。调试和发布模式构建的行为方式相同。该应用程序是 运行 来自 visual studio 和通常的 "start without debugging"。 运行 从外部控制台到 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";
}

在升级后的机器上,SetConsoleModereturnsfalse,GetLastErrorreturns87(参数不正确 ") 和 ANSI 颜色代码在后续输出中不由控制台处理。在另一台机器上,这一切都很好,并且 ansi 颜色按预期呈现。

在升级后的机器上打开控制台 window 显示 版本 10.0.10240,在另一台机器上显示 版本 10.0.14393 。虽然我有点惊讶升级后的机器没有 运行ning 更新的版本,但 运行ning 的版本应该支持 ANSI 颜色。

什么可以解释两台机器之间的行为差​​异?

直到 Windows10 阈值 2 (TH2),也称为“11 月更新”,它是版本 1511 并具有构建版本,windows 才在控制台 windows 中添加对 ANSI 转义序列的支持号码 10586。

您的“另一台机器”的版本为 10.0.14393,因此当您将适当的标志传递给 SetConsoleMode 时将获得完全支持。但是,版本为 10.0.10240 的“升级机器”无法识别 ENABLE_VIRTUAL_TERMINAL_PROCESSING 标志,因此返回“无效参数”错误。

其实就是这个officially recommended way to check whether the OS supports the extended console features:

The following code provides an example of the recommended way to enable virtual terminal processing for an application. The intent of the sample is to demonstrate:

  1. The existing mode should always be retrieved via GetConsoleMode and analyzed before being set with SetConsoleMode.
  2. SetConsoleMode returning with STATUS_INVALID_PARAMETER is the current mechanism to determine when running on a down-level system. An application receiving STATUS_INVALID_PARAMETER with one of the newer console mode flags in the bit field should gracefully degrade behavior and try again.

作为下层系统的解决方法,您可以使用 ANSICon or ConEmu.