cmd.exe / ConPTY —— ANSI 转义码支持情况
cmd.exe 是自 Windows NT 3.1(1993 年)以来每个 Windows 版本都附带的传统命令处理器。它只是一个 shell,并非终端 —— 启动时,Windows 将其标准 I/O 交给负责实际渲染的控制台宿主:在 Windows 10 及更早版本上是 conhost.exe,在 Windows 10 1809+ 与 Windows 11 上是 ConPTY(内核态伪控制台)。多数开发者踩过的历史坑是 ANSI 转义码解析:早期 conhost.exe 会忽略 \x1b[31m,把字节当字面文本渲染出来。修复在 Windows 10 1511(2015 年 11 月)落地,以 ENABLE_VIRTUAL_TERMINAL_PROCESSING 标志(通过 SetConsoleMode 调用)为选项启用;在 1709(2017 年 10 月)对大多数程序成为默认;又在 1809(2018 年 10 月)围绕 ConPTY 重建 —— 此后遗留 Win32 控制台 API 调用(SetConsoleTextAttribute、WriteConsoleW)在输出途中被翻译为 VT 字节。
2026 年的实际情况:每个仍受支持的 Windows 版本默认就解析 xterm-ctlseqs。剩余的 cmd 专属怪癖包括:用于在 BAT 脚本提示符中嵌入 ESC 的 $E 语法、处理非 ASCII 文本所需的 chcp 65001 代码页咒语,以及 ConPTY 翻译的有损性 —— 仅使用 Win32 控制台 API 的程序未必能干净地完成往返。cmd.exe 自身不输出任何彩色 —— 你在 cmd 窗口里看到的所有色彩,都是子进程通过 VT 字节绘制出来的。
最近更新
特性支持情况
该终端在站点统一矩阵跟踪的 15 个特性上的表现。点击任意特性名可查看其在全部终端上的完整支持情况。
- 8 种基础色(30–37 / 40–47)SGR 30–37 前景,40–47 背景。支持
- 高亮(aixterm)色(90–97 / 100–107)aixterm SGR 扩展。支持
- 256 色调色板(38;5;n / 48;5;n)xterm 256 色扩展。部分
- 24 位真彩色(38;2;r;g;b)1670 万直接 RGB。设置 $COLORTERM=truecolor。部分
- 斜体(SGR 3)斜体文本属性。不支持
- 扩展下划线(4:1–4:5)波浪/点/虚下划线样式。不支持
- 删除线(SGR 9)文本中央的水平线。不支持
- OSC 8 超链接内联可点击 URI。不支持
- 备用屏幕(?1049h)全屏应用缓冲区。部分
- 鼠标跟踪(SGR ?1006)鼠标点击/拖拽事件。部分
- 括号粘贴(?2004)粘贴文本被 ESC[200~/ESC[201~ 包裹。支持
- 焦点事件(?1004)获得焦点时 ESC[I,失去时 ESC[O。不支持
- Sixel 图形DEC sixel 内联位图。不支持
- Kitty 图形协议PNG/RGB 内联图像和动画。不支持
- 同步输出(?2026)原子化帧更新,避免撕裂。不支持
在此终端可用的序列
该终端能完整处理的转义序列对应的权威参考页。每条均链接到完整页面,含字节形式、规范出处与多语言示例。
细节与版本说明
在生产中使用某序列前应知晓的、该终端特有的注意事项。
- ENABLE_VIRTUAL_TERMINAL_PROCESSING —— 历史可选启用标志
- 在 1709 之前,控制台程序必须显式调用
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT)以启用 VT 解析。Python 的colorama.just_fix_windows_console()(自 0.4.6 起)与pwsh.exe的提示符初始化已替你完成;裸的python.exe/node.exe/go run在 1809+ 上由于 ConPTY 介入而隐式启用 VT。纯 C:#include <windows.h>+SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), 0x0001 | 0x0004)。PowerShell:[Console]::OutputEncoding = [System.Text.Encoding]::UTF8,无需额外操作。若 CLI 必须兼容 Win7 / Server 2008 R2,请回退到 colorama 风格的 Win32-API 路径。 - ConPTY 翻译有损 —— Win32 控制台怪癖仍会泄漏
- 自 1809 起,每个 cmd 窗口都由 ConPTY 接管:它持有屏幕缓冲、运行解析器,并向上游发送 VT 字节。仍在调用
WriteConsoleOutput或通过GetConsoleScreenBufferInfo查询屏幕缓冲状态的遗留程序,依赖 ConPTY 合成响应。已知有两类有损情况:(1) 带非默认属性的WriteConsoleOutput会被近似为最接近的 VT SGR —— 子单元格精度丢失;(2) 括号粘贴模式字节会泄漏到未请求该模式的程序,因为 ConPTY 无法判断哪个子进程预期哪种 DEC 私有模式(microsoft/terminal#3866)。绕行方案:通过IsConsoleHandle + GetConsoleMode返回ENABLE_VIRTUAL_TERMINAL_INPUT来检测 ConPTY,并只发送现代 VT。 prompt $E[1;31m…$E[0m—— 在 cmd.exe 提示符中嵌入 ESC- cmd.exe 的
prompt内建命令把$E展开为字面\x1b字节,因此prompt $E[1;31m$P$E[0m$G会把工作目录提示符渲染为红色。可通过setx PROMPT "$E[1;31m$P$E[0m$G"永久设置。在 BAT 脚本中也可用for /F %%a in ('echo prompt $E ^| cmd') do set ESC=%%a把 ESC 字节捕获到变量。现代 PowerShell 用户直接用$PSStyle.Foreground.Red;cmd 用户没有原生彩色 API —— 只有这种提示符替换技巧。 chcp 65001启用 UTF-8 —— 以及 EOF 陷阱- cmd.exe 默认使用 OEM 代码页(美式英语区域为 cp437),因此带表情符号或大多数非 ASCII 文本的彩色输出会显示为乱码。
chcp 65001将活动代码页切换为 UTF-8;可通过setx /M PYTHONUTF8 1(Python)或在 设置 → 时间和语言 → 语言和区域 → 管理语言设置 → 更改系统区域设置 → Beta:使用 Unicode UTF-8(Windows 10 1903+,机器范围)持久化。历史 EOF 陷阱:在 cp65001 下,某些 C 运行时版本会在getchar()上提前读到 EOF —— MSVC v142+ 已修复,但 mingw 构建的二进制仍受影响。SGR 转义字节本身与代码页无关(它们都是 ASCII),所以彩色在任何代码页下都能工作。 - 真彩色:自 1709 起支持,但 conhost.exe 会量化为 16 色
- Windows 10 1709+ 能解析
\x1b[38;2;R;G;Bm真彩色 SGR。在 Windows Terminal 中你拿到真正的 24 位像素;在传统 conhost.exe(直接从C:\Windows\System32\cmd.exe启动而非通过wt.exe时看到的宿主)中,真彩色值会被量化到 16 色控制台调色板中最接近的一种。在意保真度的程序应查询$COLORTERM=truecolor(Windows Terminal 设置;conhost.exe 不设置),或者 —— 更稳妥的做法 —— 发送 256 索引色作为更安全的基线。1809+ 上的 ConPTY 原样转发真彩色字节;量化发生在解析器之上的渲染层。 - $TERM 未设置 —— 使用
OS=Windows_NT检测 - cmd.exe 不设置
$TERM—— 基于 terminfo 的检测(tput colors、infocmp)会静默失败。跨平台 CLI 应检查process.platform === 'win32'(Node)、os.name === 'nt'(Python)、runtime.GOOS === "windows"(Go)、cfg!(windows)(Rust)。若要区分 "运行于 Windows Terminal" 与 "运行于裸 conhost",可查看$WT_SESSION(仅 Windows Terminal 设置)或$TERM_PROGRAM=Windows_Terminal。裸 cmd / conhost 二者皆无,只有OS=Windows_NT。在 WSL 里情形相反 ——$TERM由 Linux shell 正常设置,Windows 宿主对它不可见。