【问题标题】:How to make win32 console recognize ANSI/VT100 escape sequences?如何让 win32 控制台识别 ANSI/VT100 转义序列?
【发布时间】:2021-01-15 12:10:54
【问题描述】:

我正在构建 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 代码级别做什么?

【问题讨论】:

标签: windows terminal console-application ncurses ansi-escape


【解决方案1】:

[更新] 对于最新的 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 得到了回答:

【讨论】:

  • 我曾经做过一个 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 - 已更新答案以引用您的评论
【解决方案2】:

从 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 中创建一个名为 DWORDVirtualTerminalLevel 并将其设置为 0x1;然后重新启动 cmd.exe。 -- 可以用下面的powershell"?[1;31mele ?[32mct ?[33mroni ?[35mX ?[36mtar ?[m".Replace('?', [char]27);进行测试。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    对于 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 上的讨论
    【解决方案5】:

    基于@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。
    【解决方案6】:

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

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

    【讨论】:

    • 例如,您可以直接使用ParseAndPrintString函数重新编译应用程序。
    【解决方案7】:

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

    【讨论】:

    【解决方案8】:

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

    【讨论】:

      【解决方案9】:

      也许ANSICON可以帮助你

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

      安装:ansicon -i

      【讨论】:

        【解决方案10】:

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

        【讨论】:

          【解决方案11】:

          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 文件,你将无法设置特殊的配置和自动执行文件,它将使用默认的 CONFIG.NT。如果您只想为一个 DOS 应用程序使用一个特殊的配置文件,您可以复制“MSDOS 快捷方式”,或者您可以复制 Windows 文件夹中的“_default.pif”。

          【讨论】:

            【解决方案12】:

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

            【讨论】:

              【解决方案13】:

              我发现这个工具对我有用。 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 进行过测试。
              猜你喜欢
              • 2010-09-19
              • 1970-01-01
              • 2015-10-08
              • 1970-01-01
              • 2010-12-14
              相关资源
              最近更新 更多