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

92

我正在构建一个轻量级版本的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

C代码层面上需要做什么,才能加载ANSI.SYS驱动程序并识别ANSI/VT100转义序列?


3
请注意,截至最近的Windows 10版本,游戏规则已经发生了巨大变化。 - Andreas Rejbrand
5
FYI,在最新的Windows 10中,您可以通过以下reghack在conhost中启用ANSI -- 在HKCU\Console中创建名为VirtualTerminalLevelDWORD,并将其设置为0x1;然后重新启动cmd.exe。-- 您可以使用以下PowerShell进行测试"?[1;31mele ?[32mct ?[33mroni ?[35mX ?[36mtar ?[m".Replace('?', [char]27); - BrainSlugs83
1
这里是如何在不编辑注册表的情况下启用它,从而避免可能破坏其他应用程序的例子。 - Bogdan Mart
ANSI.SYS是我自从WIN98时代以来就再也没见过的东西。 - Luiz Felipe
显示剩余3条评论
14个回答

2
Ansi.sys(位于system32文件夹中)是Windows XP、2000和早期版本的NT提供的“MSDOS驱动程序”。在2000年和XP中,它位于system32文件夹中(我不记得早期版本的NT的结构)。在运行于DOS子系统并使用标准输出的程序中,可以像在MSDOS上运行一样使用ANSI.SYS。
要加载ansi.sys,必须在config中使用device=或devicehigh=命令,就像在MSDOS中一样。在Windows NT 5(2K和XP)中,每个DOS子系统副本都可以在pif/shortcut中给出单独的config文件(使用“高级”按钮),并且有一个名为CONFIG.NT的默认文件(也位于system32文件夹中),如果pif/shortcut没有指定特殊的config文件,则使用该文件。
当 ansi.sys 被正确加载时,mem /d 将报告它已被加载。在早期版本的 NT 上,您可以并且必须加载一个适当的 DOS 环境来加载 ansi.sys,并且 ANSI 艺术将在提示符处工作。在 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文件。如果您创建一个.lnk文件到CMD,您将无法设置特殊的config和autoexec文件,它将使用默认的CONFIG.NT。如果您想要为一个DOS应用程序使用特殊的config文件,您可以复制“MSDOS快捷方式”,或者您可以复制在Windows文件夹中找到的“_default.pif”。

2
我个人喜欢使用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脚本自动完成。
  • 彩色和可编写脚本的提示符。
  • 自动回答“Terminate batch job?”提示。

2
遇到了同样的问题。我安装了ConEmu,这个解决了我的问题。

0

在Windows中,您只需要首先调用任何shell命令,而不是调用system函数。只需在主方法的开头放置system("");,并别忘了包含stdlib.h

当我查看一些旧程序时,我注意到这一点,这些程序也使用ANSI代码来理解它们为什么有效,但我的新代码却没有。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接