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

Roo*_*ook 4 winapi visual-studio windows-console

我最近将我的一台电脑从 Windows 7 专业版升级到了 Windows 10 专业版。我正在尝试运行一些我知道正在另一台 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";
}
Run Code Online (Sandbox Code Playgroud)

在升级后的机器上,SetConsoleMode返回false,GetLastError返回87(“参数不正确”)并且ANSI颜色代码在后续输出中不被控制台处理。在另一台机器上,这一切都很好,ansi 颜色按预期呈现。

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

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

Cod*_*ray 5

直到 Windows 10 阈值 2 (TH2),也称为“十一月更新”,版本 1511 并具有内部版本号 10586,才在控制台窗口中添加对 ANSI 转义序列的支持。

因此,当您将适当的标志传递给SetConsoleMode. 但是,版本为 10.0.10240 的“升级机器”无法识别该ENABLE_VIRTUAL_TERMINAL_PROCESSING标志,因此返回“无效参数”错误。

事实上,这是官方推荐的检查操作系统是否支持扩展控制台功能的方法

以下代码提供了为应用程序启用虚拟终端处理的推荐方法示例。样本的目的是证明:

  1. 现有模式应始终通过检索GetConsoleMode并分析,然后再使用SetConsoleMode.
  2. SetConsoleMode返回 withSTATUS_INVALID_PARAMETER是当前确定何时在下层系统上运行的机制。STATUS_INVALID_PARAMETER在位字段中使用较新的控制台模式标志之一接收的应用程序应该优雅地降低行为并重试。

作为下层系统的解决方法,您可以使用ANSIConConEmu

  • 使用诸如 PDCurses 之类的库或其他抽象 Windows 控制台 API 的库可能比 ANSICON 更好,ANSICON 基于 DLL 注入和 API 挂钩。 (2认同)