如何使 win32控制台识别 ANSI/VT100转义序列?

我正在构建一个轻量级版本的 ncurses 库。到目前为止,它与 VT100兼容的终端工作得很好,但 win32控制台无法识别 \033代码作为转义序列的开始:

# include <stdio.h>
# include "term.h"


int main(void) {
puts(BOLD COLOR(FG, RED) "Bold text" NOT_BOLD " is cool!" CLEAR);
return 0;
}

Screenshot

为了加载 ANSI.SYS 驱动程序并识别 ANSI/VT100转义序列,在 C 代码级需要做些什么?

91897 次浏览

为了给 cmd 上色,你需要使用 Windows.hSetConsoleTextAttribute(),更多的细节可以在 http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047%28v=vs.85%29.aspx中找到

[更新]关于最新的 Windows 10,请阅读@brain slugs83的有用贡献,就在下面对这个答案的评论中。

而对于 Windows 10 Anniversary Update之前的版本:

ANSI.SYS 有一个限制,它只能在 Windows 95-Vista 下的 MS-DOS 子系统上下文中运行。

Microsoft KB101875解释了如何在命令窗口 但它不适用于 WindowsNT中启用 ANSI.SYS。根据这篇文章: 我们都喜欢颜色,现代版本的 Windows 没有这个很好的 ANSI 支持。

相反,微软创建了很多函数,但这远远不需要操作 ANSI/VT100转义序列。

有关更详细的解释,请参阅 维基百科文章:

SYS 也适用于 NTVDM 下执行的16位遗留程序的 NT 派生系统。

Win32控制台根本不支持 ANSI 转义序列。然而,像 安西康这样的软件可以充当标准 Win32控制台的包装器,并添加对 ANSI 转义序列的支持。

所以我认为 Jason Hood 的 安西康是你的解决方案。它是用 C编写的,支持32位和64位版本的 Windows 和 消息来源是可用的

我还发现了一些其他类似的问题或帖子,最终得到了使用 ANSICON 的回答:

如果 ANSICON 是不可接受的,因为它要求您安装在系统上的东西,一个更轻量级的解决方案,解析和转换到相关的 Win32API 控制台函数,如 属性的 ANSICON 代码。

Https://github.com/mattn/ansicolor-w32.c

从 Windows10TH2(v1511)开始,conhost.execmd.exe支持 ANSI 和 VT100开箱即用的逃逸序列(尽管是 它们必须被激活)。

有关详细信息,请参阅 我在超级用户上的回答

从 Windows10开始,您可以使用 ENABLE_VIRTUAL_TERMINAL_PROCESSING来启用 ANSI 转义序列:

Https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx

对于 Python 2.7,下面的脚本可以在 Windows 10(v1607)中使用

import os


print '\033[35m'+'color-test'+'\033[39m'+" test end"
os.system('') #enable VT100 Escape Sequence for WINDOWS 10 Ver. 1607
print '\033[35m'+'color-test'+'\033[39m'+" test end"

结果应该是:

[35mcolor-test[39m test end


color-test test end

也许 安西康能帮你

只需下载和解压文件,取决于您的 Windows 操作系统: 32位或64位

使用: ansicon -i安装它

我个人喜欢 干杯。它不仅处理 ANSI 代码,它还增加了许多其他功能,所以 Windows 控制台的行为就像 Bash(历史,反向历史搜索,键盘快捷键等) :

  • 与 Bash 相同的行编辑(来自 GNU 的 Readline 库)。
  • 会话之间的历史持久性。
  • 上下文敏感完成;
    • 可执行文件(和别名)。
    • 目录命令。
    • 环境变量
    • 第三方工具; Git、 Mercurial、 SVN、 Go 和 P4。
  • 新的键盘快捷键;
    • 从剪贴板粘贴(Ctrl-V)。
    • 增量历史搜索(Ctrl-R/Ctrl-S)。
    • 强大的完成(TAB)。
    • 撤销(Ctrl-Z)。
    • 自动“ cd. .”(Ctrl-PgUp)。
    • 环境变量膨胀(Ctrl-Alt-E)。
    • (请按 Alt-H获取更多信息...)
  • 使用 Lua 完成脚本。
  • 彩色和可编写脚本的提示符。
  • 自动回答“ 终止批处理作业?”提示。

Sys (在 system32文件夹中)是一个“ MSDOS 驱动程序”,作为 Windows XP、2000和 NT 早期版本的一部分提供。在2000年和 XP 中,它位于 system32文件夹(我不记得 NT 早期版本的结构)。在 DOS 子系统中运行并使用标准输出的程序可以使用 ANSI.SYS,就像它们可以在 MSDOS 上运行一样。

要加载 ansi.sys,必须在 config 中使用 device = 或 devicehigh = 命令,就像在 MSDOS 中一样。在 Windows NT 5(2K & XP)中,DOS 子系统的每个副本都可以在 pif/快捷方式中获得一个单独的配置文件(使用“高级”按钮) ,并且有一个名为 CONFIG.NT 的默认文件(也在 system 32文件夹中) ,如果 pif/快捷方式没有指定一个特殊的配置文件,则使用该文件。

当正确加载 ansi.sys 时,mem/d 将报告它已经加载。在 NT 的早期版本中,您可以而且必须加载适当的 DOS 环境来加载 ansi.sys,而 ansi art 将在提示符下工作。在 Win 2K 和 XP 上,加载 ansi.sys 对“ CMD 提示符”没有影响,因为 CMD 不是 DOS 程序: 它是一个32位 Windows 控制台程序。出于某种原因,我不明白,在 WinXP 上,即使你使用“ command.com/p”加载 command.com 的固定副本,命令提示符也不会启用 ansi: 也许当你这样做时,它只模拟加载 command.com?

在任何情况下,当您使用 command.com 的实际 DOS 版本时,在加载之后启用了 ansi : 您可以通过一点 ansi 艺术来演示它的用法,如下所示:

command /c type ansiart.ans

(这里有一个例子: http://artscene.textfiles.com/ansi/artwork/beastie.ans)

NT (在 system32文件夹中)包含加载设备驱动程序的语法示例。您需要是一名管理员才能编辑该默认文件,或者您可以复制该文件。

在 Win2K 和 XP 上,MSDOS 的默认“快捷方式”是。PIF 文件,不是。LNK 档案。如果创建一个。将 lnk 文件设置为 CMD,您将无法设置特殊的配置和 autoexec 文件,它将使用默认的 CONFIG.NT。如果只想为一个 DOS 应用程序使用特殊的配置文件,可以复制“ MSDOS 快捷方式”,也可以复制 Windows 文件夹中的“ _ default.pif”。

我发现这个工具对我有用。 来自 GitHub 的微软彩色工具

解压缩文件,然后打开具有管理权限的 CMD。

转到您在 CMD 中解压缩文件的文件夹。

然后执行这个命令“ colortool -b scheme-name

方案名称需要替换为以下任一选项:

  • Campbell ini
  • Campbell 的遗产 ini
  • Cmd-遗产。 ini
  • Deuternopia.iterm 颜色
  • OneHalfDark. itermcolor
  • OneHalfLight.itermcolor
  • 文字色彩
  • 光线

在我的例子中,命令类似于“ colortool -b solarized_dark.itermcolors

在控制台窗口上单击右键并选择“属性”。

您不需要更改任何值,只需单击“确定”保存设置。(您将注意到您的字体已经包含颜色)。

控制台财产

然后重新启动 cmd 或 powerShell。

ANSI 颜色应该启用,并使用您之前选择的配色方案。

在最新的 win10中,它可以由 SetConsoleMode(originMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)完成。参见 https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#example

遇到了同样的问题。我安装了 科尼姆,这个解决了我的问题。

基于@BrainSlugs83,你可以通过寄存器激活当前的 Windows 10版本,命令行如下:

REG ADD HKCU\CONSOLE /f /v VirtualTerminalLevel /t REG_DWORD /d 1

在 Windows 中,您只需要首先调用任何 shell 命令,而不是调用 system函数。在你的主方法的开始,放入 system("");,不要忘记包括 stdlib.h

我注意到这一点,当我看到我的一些旧程序,也使用 ANSI 代码,以了解为什么他们的工作,但我的新代码不是