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 宿主对它不可见。