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

时间:2017-06-11 09:55:53

标签: visual-studio winapi windows-console

我最近将一台电脑从Windows 7专业版升级到Windows 10专业版。我试图运行一些我知道正在使用另一台Windows 10机器的代码(从一开始就是win10 pro)。在这两种情况下,我都使用Visual Studio Community 2017,目标平台是Windows 10,平台工具集是v141。我尝试了几个不同的Windows SDK版本,但没有改变结果。调试和发布模式构建的行为方式相同。该应用程序是从visual studio运行的,通常是#34;启动时没有调试"。从外部控制台运行到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(&#34; 参数不正确&#34;),ANSI颜色代码为在后续输出中未由控制台处理。在另一台机器上,这一切都很好,并且ansi颜色按预期呈现。

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

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

1 个答案:

答案 0 :(得分:4)

在Windows 10阈值2(TH2)之前,未添加对控制台窗口中的ANSI转义序列的支持,也称为“11月更新”,即1511版本,内部版本号为10586.

因此,当您将适当的标记传递给SetConsoleMode时,版本为10.0.14393的“其他计算机”将完全支持。但是,版本为10.0.10240的“已升级的计算机”无法识别ENABLE_VIRTUAL_TERMINAL_PROCESSING标志,因此返回“无效参数”错误。

实际上,这是officially recommended way to check whether the OS supports the extended console features

  

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

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

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