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

Posted

技术标签:

【中文标题】如何让 win32 控制台识别 ANSI/VT100 转义序列?【英文标题】:How to make win32 console recognize ANSI/VT100 escape sequences? 【发布时间】:2013-05-21 05:53:52 【问题描述】:

我正在构建 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;

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

【问题讨论】:

Python 有 colorama 模块:"On Windows, Colorama strips these ANSI characters from stdout and converts them into equivalent win32 calls for colored text. On other platforms, Colorama does nothing." 请注意,自最新版本的 Windows 10 起,游戏规则发生了巨大变化。 仅供参考,在最新的 Windows 10 中,您可以通过以下 reghack 在 conhost 中启用 ANSI -- 在 HKCU\Console 中创建一个名为 DWORDVirtualTerminalLevel 并将其设置为 0x1;然后重新启动 cmd.exe。 -- 可以用下面的powershell"?[1;31mele ?[32mct ?[33mroni ?[35mX ?[36mtar ?[m".Replace('?', [char]27);进行测试。 在此处更新docs.microsoft.com/en-us/windows/console/… 如何在不编辑注册表并可能破坏其他应用程序的情况下启用它 【参考方案1】:

要为 cmd 着色,您需要 Windows.h 并使用 SetConsoleTextAttribute() 更多详细信息可以在 http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047%28v=vs.85%29.aspx 中找到

【讨论】:

这是一个相当笨拙的解决方案,更不用说它只允许为文本着色 - 而不是其余的 ANSI.SYS 代码。 users.cybercity.dk/~bse26236/batutil/help/ANSI~S_S.HTM【参考方案2】:

[更新] 对于最新的 Windows 10,请阅读@brainslugs83 的有用贡献,就在此答案的 cmets 下方。

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

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

Microsoft KB101875 解释了如何在命令窗口中启用 ANSI.SYS,但它不适用于 Windows NT。根据文章:we all love colors,现代版本的 Windows 没有这种很好的 ANSI 支持。

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

更详细的解释见Wikipedia article:

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

Win32 控制台根本不支持 ANSI 转义序列。但是,Ansicon 等软件可以充当标准 Win32 控制台的包装器,并添加对 ANSI 转义序列的支持。

所以我认为 Jason Hood 的 ANSICON 是您的解决方案。它是用C编写的,支持32位和64位版本的Windows,以及the source is available。

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

How to load ANSI escape codes or get coloured file listing in WinXP cmd shell? how to use ansi.sys in windows 7 How can I get cmd.exe to display ANSI color escape sequences? ansi color in windows shells enable ansi colors in windows command prompt

【讨论】:

我曾经做过一个 hack,让 ANSI 在没有任何第三方工具的情况下在 Windows XP 中工作 groups.google.com/forum/#!topic/alt.msdos.batch.nt/YZnoq80Mcds 时代如何变化 ;) 在 Windows 10 周年更新及更高版本中,Windows 控制台进行了更新,对 ANSI/VT 序列提供了相当可靠的支持,在创作者更新中,也进行了更新以支持 24 位 RGB 颜色:blogs.msdn.microsoft.com/commandline/2016/09/22/… @Simon 谢谢,我删除了链接,因为它不起作用 btw 有一个 archived version of kb/101875 here 仅供参考,在最新的 Windows 10 中,您可以通过以下 reghack 在 conhost 中启用 ANSI -- 在 HKCU\Console 中创建一个名为 DWORDVirtualTerminalLevel 并将其设置为 0x1;然后重新启动 cmd.exe。 -- 可以用下面的powershell"?[1;31mele ?[32mct ?[33mroni ?[35mX ?[36mtar ?[m".Replace('?', [char]27);进行测试。 感谢@brainslugs83 - 已更新答案以引用您的评论【参考方案3】:

如果 ANSICON 不可接受,因为它要求您在系统上安装某些东西,则可以使用更轻量级的解决方案,将 ANSI 代码解析并转换为相关的Win32 API console functions,例如SetConsoleTextAttribute。

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

【讨论】:

例如,您可以直接使用ParseAndPrintString函数重新编译应用程序。【参考方案4】:

从 Windows 10 TH2 (v1511) 开始,conhost.execmd.exe 支持开箱即用的 ANSI 和 VT100 转义序列(尽管 they have to be enabled)。

更多详情请见my answer over at superuser。

【讨论】:

105xx 版本是唯一默认启用 VT100 序列的版本。在以前和以后的版本中,默认情况下它是禁用的,因为它被错误地启用了。解释见这里wpdev.uservoice.com/forums/… 仅供参考,在最新的 Windows 10 中,您可以通过以下 reghack 在 conhost 中启用 ANSI -- 在 HKCU\Console 中创建一个名为 VirtualTerminalLevelDWORD 并将其设置为 0x1;然后重新启动 cmd.exe。 -- 可以用下面的powershell"?[1;31mele ?[32mct ?[33mroni ?[35mX ?[36mtar ?[m".Replace('?', [char]27);进行测试。【参考方案5】:

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

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

【讨论】:

【参考方案6】:

对于 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 10 (v1703) 上的 Python 3。 (即print('\033[35m'+'color-test'+'\033[39m'+" test end") 有人有消息来源或知道os.system('') 对控制台的更改吗? os.system('') 工作显然是因为 cmd.exe 中的错误(cmd.exe 启用 VT 模式,但不会在退出时禁用它)。有关更多信息以及启用 VT 模式的更好代码,请参阅issue 30075 on python.org 上的讨论【参考方案7】:

也许ANSICON可以帮助你

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

安装:ansicon -i

【讨论】:

【参考方案8】:

我个人喜欢clink。它不仅处理 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 编写脚本完成。 彩色和可编写脚本的提示。 自动回答“终止批处理作业?”提示。

【讨论】:

【参考方案9】:

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

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

当 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?

在任何情况下,当您使用实际的 DOS 版本的 command.com 时,ansi 在加载后启用的:您可以像这样通过一些 ansi 艺术来演示它的使用:

command /c type ansiart.ans

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

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

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

【讨论】:

【参考方案10】:

我发现这个工具对我有用。 Microsoft Color Tool from GitHub

解压缩压缩文件,然后以管理员权限打开 CMD。

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

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

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

campbell.ini campbell-legacy.ini cmd-legacy.ini deuternopia.itermcolors OneHalfDark.itermcolors OneHalfLight.itermcolors solarized_dark.itermcolors solarized_light.itermcolors

在我的例子中,命令应该是这样的“colortool -b solarized_dark.itermcolors

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

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

Console Property

然后重新启动你的 cmd 或 powerShell。

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

【讨论】:

我试过这个,然后 docker-machine 拒绝连接。 很抱歉这么久,但上述方法从未针对 docker 进行过测试。【参考方案11】:

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

【讨论】:

【参考方案12】:

有同样的问题。我安装了ConEmu,那个解决了我的问题。

【讨论】:

【参考方案13】:

基于@BrainSlugs83,您可以使用以下命令行在当前的 Windows 10 版本上通过注册激活:

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

【讨论】:

所有 Windows 10 版本都支持此功能吗?还是可以通过特定更新获得? 不支持 Windows 10 的第一个版本,但在当前版本中可以正常工作。 我想知道支持这个的具体版本。 @Youssef13 根据superuser.com/a/1300251/702169,第一个支持版本是build 16257。

以上是关于如何让 win32 控制台识别 ANSI/VT100 转义序列?的主要内容,如果未能解决你的问题,请参考以下文章

libusb-win32 支持win10吗

在win32 application下如何修改应用程序图标?

win10无法识别usb设备怎么办

如何设置让Win10可以ping通

win10系统,如何设置能够让别人远程协助时能完全控制我的电脑

win10识别不了usb设备怎么办