Windows Terminal wt 命令行参数设计全解:从 607 设计规格到 CLI11 源码实现
2026/9/7 4:32:42 网站建设 项目流程

Windows Terminal wt 命令行参数设计全解:从 #607 设计规格到 CLI11 源码实现

【免费下载链接】terminalThe new Windows Terminal and the original Windows console host, all in the same place!项目地址: https://gitcode.com/GitHub_Trending/term/terminal

本文以仓库中 doc/specs/#607 - Commandline Arguments for the Windows Terminal.md 设计规格为主体,系统讲解 Windows Terminal 的wt命令行参数体系:为什么采用“命令 + 参数”双段式设计、new-tab/split-pane/move-focus等子命令与参数如何组合使用、分号分隔与转义规则背后的取舍,并结合当前仓库中 AppCommandlineArgs.cpp、Commandline.cpp 等源码,验证规格设计是如何落地的、后续又演化成了什么样。

背景:为什么需要 wt 命令行参数

规格的 Abstract 部分开宗明义:这套参数用于支持“定制化启动场景”,例如直接以指定 profile 或指定目录启动终端。其灵感来源(Inspiration)与几个历史需求直接相关:

  • wt.exe这个执行别名出现后,社区一直希望它能接受参数,从而描述“以何种方式启动”;
  • issue #576 希望任务栏 jumplist 中显示 Windows Terminal 的入口,但当时无法向 Terminal 传达“要启动哪个 profile”,因此被阻塞;
  • issue #1060 希望资源管理器右键菜单的“在此处打开 Windows Terminal”更强大——能指定在该目录中以某个特定 profile 启动;
  • issue #2068 希望从 Terminal 内部不仅能打开默认 profile 的新窗口,还能打开指定 profile 的新窗口。

规格还提到,最终的参数设计深受tmux命令行参数风格的启发——后者同样支持通过命令行参数完成复杂的启动编排。

14 个用户故事:需求侧的完整清单

规格文档列举了 14 个用户故事来引导设计,这也是理解参数体系完备性的基准。完整继承如下:

  1. 以默认 profile 打开 Windows Terminal(只需wt,已天然支持);
  2. 以 profile 列表中的某个特定 profile 打开;
  3. 以默认 profile 打开,但运行一条不同于平常的命令;
  4. 查看wt.exe支持的参数列表;
  5. 查看 profile 列表,以便从中挑选一个打开;
  6. 不打开终端窗口,直接打开设置文件;
  7. 不打开终端窗口,查看当前 Windows Terminal 版本;
  8. 在屏幕的特定位置打开终端窗口;
  9. 在特定目录中打开终端;
  10. 以特定尺寸打开终端;
  11. 只使用默认设置、忽略用户设置打开终端;
  12. 同时打开多个标签页,各标签页使用不同 profile、不同启动目录,甚至不同命令行;
  13. 同时打开多个标签页和窗格,各自拥有不同 profile、启动目录、命令行,并指定分割大小;
  14. 用一个文件提供可复用的多步骤启动配置,避免每次手敲命令行。

这 14 个故事覆盖了“信息查询、窗口控制、多标签/多窗格编排、可复用配置”四大类诉求,后面的命令与参数设计逐一回应它们。

设计演进:从“纯参数”到“命令 + 参数”

方案一:纯参数风格(被否决)

规格最初考虑的参数风格是:

--help: 显示帮助 --version: 显示版本信息 --list-profiles: 显示可用 profile 列表 --all 同时显示 "hidden" profile --verbose? 是否同时显示 GUID --open-settings: 打开设置文件 --profile <name>: 以指定名称的 profile 启动 --guid <guid>: 以指定 GUID 的 profile 启动 --startingDirectory <path>: 在指定目录启动 --initialRows <rows>, --initialCols <cols>: 以特定尺寸启动 --initialPosition <x,y>: 在屏幕特定位置启动 -- <commandline>: 用指定命令行启动

规格明确指出该方案的致命缺陷:难以表达“同时启动多个标签页或窗格”。用户如何为每个窗格指定不同命令行?配置越复杂,命令行就越难解析和理解。

方案二:命令(Commands)+ 参数(Parameters)

最终设计按职责把参数分为两类,这是理解wt语法的基石:

  • 命令(Commands):触发某件事的参数,使用kebab-case(如new-tabsplit-pane),可带若干可选或必需参数;
  • 参数(Parameters):为命令提供附加信息的参数,有长格式--camelCase(双连字符 + 驼峰命名)与短格式-c(单连字符 + 单个字母)两种。

wt 命令行的总体语法

wt命令行分为两大部分——“Options(选项)”与“Commands(命令)”:

wt [options] [command ; ]...
  • Options是一组作用于整个wt命令行行为的开关与参数;
  • Commands是用分号;分隔的命令及其参数列表。

两条关键规则(这也是规格中最容易被忽略、但源码中确有实现保障的行为):

  1. 缺省命令是new-tab:如果某个 command 没有显式写出命令名,就默认视为new-tab。因此wt cmd.exe等价于wt new-tab cmd.exe
  2. 空命令也是new-tabwt ; ; ;会打开 Windows Terminal 并创建4 个新标签页,等价于wt new-tab ; new-tab ; new-tab ; new-tab

关于“默认命令应该是new-window还是new-tab”,规格中保留了一段设计者的手稿笔记(原文以 HTML 注释形式留在文档里):new-window适合承载--initialPosition--initialRows/--initialCols并隐含new-tab,但同一窗口内的后续命令必须显式写new-tab,否则会各开一个窗口;若默认是new-tab,则后续new-tab会继承父窗口尺寸、忽略尺寸参数——这在语义上可以接受(第一个 tab 决定窗口大小后,其余 tab 确实无法再改)。最终结论是new-tab作为默认命令

完整示例命令行(规格原文继承)

以下示例逐条对应上面的用户故事,可直接复制使用(PowerShell 下的转义注意事项见后文):

# 以新标签页运行 "Windows Powershell" profile(用户故事 2) wt new-tab --profile "Windows Powershell" wt --profile "Windows Powershell" wt -p "Windows Powershell" # 以新标签页运行默认 profile,并执行 cmd.exe(用户故事 3) wt cmd.exe # 显示帮助文本(用户故事 4) wt help wt --help wt -h wt -? wt /? # 输出 profile 列表(用户故事 5) wt list-profiles # 不打开终端窗口直接打开设置文件(用户故事 6) wt open-settings # 显示 Windows Terminal 版本信息(用户故事 7) wt version wt --version wt -v # 在目录 "c:/Users/Foo/dev/MyProject" 中启动默认 profile(用户故事 9) wt new-tab --startingDirectory "c:/Users/Foo/dev/MyProject" wt --startingDirectory "c:/Users/Foo/dev/MyProject" wt -d "c:/Users/Foo/dev/MyProject" # Windows 风格路径同样有效 wt -d "c:\Users\Foo\dev\MyProject" # 组合:以 "Windows Powershell" profile 在指定目录打开新标签(用户故事 2、9) wt new-tab --profile "Windows Powershell" --startingDirectory "c:/Users/Foo/dev/MyProject" wt --profile "Windows Powershell" --startingDirectory "c:/Users/Foo/dev/MyProject" wt -p "Windows Powershell" -d "c:/Users/Foo/dev/MyProject" # 一个标签用 "Windows Powershell",另一个标签用 "cmd" profile(用户故事 12) wt new-tab --profile "Windows Powershell" ; new-tab --profile "cmd" wt --profile "Windows Powershell" ; new-tab --profile "cmd" wt --profile "Windows Powershell" ; --profile "cmd" wt --p "Windows Powershell" ; --p "cmd" # 以新标签运行 "my-commandline.exe with some args" wt new-tab my-commandline.exe with some args wt my-commandline.exe with some args # 第一个标签运行带字面分号的命令,第二个标签运行 another.exe wt my-commandline.exe with some args and a \; literal semicolon ; new-tab another.exe running in a second tab # 启动 cmd.exe,然后垂直分割(前者 70%、新窗格 30%),在新窗格中运行 wsl.exe(用户故事 13) wt cmd.exe ; split-pane --target 0 -V -% 30 wsl.exe wt cmd.exe ; split-pane -% 30 wsl.exe # 默认 profile 新窗口 → 垂直分割(默认 profile)→ 在第二个窗格中水平分割并运行 "media.exe"(用户故事 13) wt new-tab ; split-pane -V ; split-pane --target 1 -H media.exe wt new-tab ; split-pane -V ; split-pane -t 1 -H media.exe

选项(Options)参考

选项作用
--help,-h,-?,/?执行help命令
--version,-v执行version命令
--session,-s session-id在已存在的 Windows Terminal 会话中执行这些命令,从而可以在已经在运行的窗口中打开新标签。规格中注明该特性依赖其他计划内的工作,当时仅作为示例(详见下文“未来展望”)
--file,-f configuration-file从配置文件读取命令列表,用于可复用的启动配置(用户故事 14)

命令(Commands)参考

规格定义的完整命令集如下,每个命令的语法、参数与语义完整保留。

help

help

显示帮助信息。

version

version

显示 Windows Terminal 的版本信息。

open-settings

open-settings [--defaults,-d]

打开设置文件。当它是唯一的命令时,不会打开终端窗口(规格在“潜在问题”一节还特别强调:wt open-settings本身不应隐含new-tab)。

  • --defaults,-d:打开defaults.json而不是profiles.json

list-profiles

list-profiles [--all,-A] [--showGuids,-g]

按行列出每个可用 profile 的名称。

  • --all,-A:显示全部 profile,包括标记了"hidden": true的;
  • --showGuids,-g:除名称外同时列出 profile 的 GUID。规格建议 GUID 放在每行最前面,以便脚本解析输出。

new-tab

new-tab [--initialPosition x,y]|[--maximized]|[--fullscreen] [--initialRows rows] [--initialCols cols] [terminal_parameters]

以给定自定义方式打开新标签页。第一次调用时同时创建新窗口,之后的new-tab都在同一个窗口内创建标签。

  • --initialPosition x,y:以像素坐标在屏幕指定位置创建新窗口。仅在最初创建窗口时使用,后续new-tab忽略;与--maximized/--fullscreen组合会向用户显示“参数组合非法”的报错;
  • --initialRows rows:以rows行(字符行)创建窗口,缺省则使用用户设置中的值。同样仅在首次创建窗口时生效,与--maximized/--fullscreen冲突时报错;
  • --initialCols cols:以cols列创建窗口,规则同上;
  • [terminal_parameters]:见下文“terminal_parameters”。

split-pane

split-pane [--target,-t target-pane] [-H]|[-V] [--percent,-% split-percentage] [terminal_parameters]

当前聚焦标签页中,将指定窗格按垂直或水平方向分割出新窗格。

  • --target,-t target-pane:在指定窗格上做分割。每个窗格在标签页内有唯一索引,按创建顺序分配;缺省为当前聚焦窗格的索引;
  • -H/-V:指定分割方向。-V是“vertical”(想象[|]),-H是“horizontal”(想象[-])。缺省为“auto”——沿当前窗格的较大维度分割;若-H-V同时给出,取垂直;
  • --percent,-% split-percentage:新窗格占父窗格空间的百分比,缺省 50%;
  • [terminal_parameters]:同上。

focus-tab

focus-tab [--target,-t tab-index]

把焦点移动到指定标签页。

  • --target,-t tab-index:移动到索引为tab-index的标签,缺省为0(第一个标签)。

focus-pane

focus-pane [--target,-t target-pane]

在当前聚焦标签页内,把焦点移动到指定窗格。

  • --target,-t target-pane:移动到指定索引的窗格(索引按创建顺序分配);缺省为当前聚焦窗格(等价于 no-op)。

move-focus

move-focus [--direction,-d direction]

在当前聚焦标签页内按方向移动焦点。

  • --direction,-d directiondirection取值为leftrightupdown之一;缺省则不移动焦点(no-op)。

[terminal_parameters]

new-tabsplit-pane这类“创建新终端实例”的命令都接受一组[terminal_parameters]

[--profile,-p profile-name] [--startingDirectory,-d starting-directory] [commandline]
  • --profile,-p profile-name:以指定 profile 打开新标签/窗格,profile-name可以是 profile 的nameguid;如果不匹配任何profile,则回落到默认 profile;
  • --startingDirectory,-d starting-directory:覆盖所选 profile 的startingDirectory,改为在starting-directory启动;
  • commandline:替换所选 profile 的默认命令行。如果该命令行本身需要包含;,必须写成\;转义。

规格还对“为什么参数长这样”给出了设计论证:

  • 从原理上说,所有profile 属性都可以被命令行参数覆盖。实践上没有必要为每个 Profile 属性都做短格式参数,但长格式完全合理;
  • 之所以只选了这几个参数,是因为它们既有 profile 属性的特例(guidname),又是高优先级属性。name/guid本身没有覆盖意义,于是被“征用”为选择 profile 的参数;
  • commandline是特殊案例——没有用显式参数标记它的起点,目的是避免对用户命令行做二次解析与转义;
  • startingDirectory是被强烈请求的参数,因此在规格中被优先收录。

源码印证:规格是如何落地的

规格在 Implementation Details 一节记录了关键技术决策,当前仓库的源码可以逐条印证,并展示了规格之后发生的设计演化。

CLI11 + ActionAndArgs:解析层与动作层的分工

规格确定使用开源库 CLI11 解析参数(2019 年 11 月 18 日当周的调研结论),在 CLI11 之上增加“以;分离命令”的逻辑。每个命令解析后构造一个ActionAndArgs,复用终端内部已有的动作模型(开新标签、开新窗格、移动焦点等)。

这一决策在 AppCommandlineArgs.cpp 中直接可见:解析器就是一个CLI::App _app{ "wt - the Windows Terminal" },各子命令通过add_subcommand构建;ParseCommand 负责解析单条命令,解析出的动作统一推入_startupActionsstd::vector<ActionAndArgs>)。

规格提到的另一个工程难点——启动时子控件尚未初始化,不能一次性创建所有分割与标签(否则会开出 0x0 大小的窗格)——因此采用“逐条分发启动动作,等前一个动作对应的终端初始化完成后再分发下一个”的策略。这与 CommandlineTest.cpp 中的验证用例共同构成了该特性的可测试性基础。

分号分隔与\;转义的实现

规格规定:wt命令行以;分隔多个命令,命令行文本内的字面分号写作\;。这一规则在源码中的实现分两层:

  1. 切分:AppCommandlineArgs::BuildCommands 把原始 argv 切成多个Commandline对象。内部使用正则^;|[^\\];(见 AppCommandlineArgs.cpp 第 13 行,注释即“行首的;,或前面不是\;)匹配未转义的分界符。值得注意的细节在 _addCommandsForArg:每切出一个新命令,都会先向其中注入占位首参wt.exe(第 952 行),这样后续每条命令都能像用户单独敲出wt一样被统一解析——这也解释了为什么wt ; ; ;会展开成 4 条命令;
  2. 反转义:Commandline.h 定义了Delimiter{ L";" }EscapedDelimiter{ L"\\;" }两个常量;Commandline::AddArg 在参数入列时循环查找并把\;替换回;,保证下游拿到的就是字面分号。

规格“Potential Issues”中预判“转义是出了名的难做对,需要大量测试”——仓库中的 CommandlineTest.cpp 印证了这一点:除TestEscapeDelimiters外,ParseSimpleCommandline(第 120-180 行)专门断言了wt.exenew-tab ;;; ;这些边界输入各自切分出正确数量的命令,且后续命令的首参是占位符wt.exe

隐式 new-tab 的双重保障

规格“Potential Issues”一节讨论过:如果new-tab不是第一个命令(例如wt split-pane -V ; new-tab),怎么办?团队最终结论是假定存在一条隐式new-tab先执行,以保证“wt.exe不带任何参数时本来就是隐式new-window/new-tab”这一易用性语义不被破坏。

这个决定在源码中有两层落地:

  • ParseCommand:如果一条命令解析完后没有任何子命令_noCommandsProvided()为真),就把剩余参数当作new-tab子命令重新解析。这解释了为什么wt cmd.exewt new-tab cmd.exe等价;
  • ValidateStartupCommands:如果动作队列为空、或队首动作不是NewTab,就在队首补插一条NewTab动作。CommandlineTest.cpp中的ValidateFirstCommandIsNewTabParseNoCommandIsNewTab测试方法正是针对这两条路径的验证。

规格的演化:从 2020 年草稿到当前实现

规格文档的“Implementation plan”用勾选框记录了分步落地过程(重构ShortcutAction分发为独立类、新增带split参数的SplitPane动作、给NewTabArgs/SplitPaneArgs加入TerminalParameters对象、给SplitPanepercent参数、在TerminalApp中加入解析与测试等)。对照当前仓库可以观察到规格之后发生的几处可确认的演化(以下均以当前源码为准):

  • 窗口尺寸/位置参数换名:规格中的--initialPosition x,y--initialRows--initialCols在当前实现中演化为--pos(按名称指定位置,见 LaunchPositionFromString 回调)与--sizeSizeFromString解析,第 191-194 行);--maximized--fullscreen则收敛为全局 flag-M/-F,并新增了-f,--focus专注模式,三者之间通过 CLI11 的excludes约束互斥关系(第 166-194 行);
  • 命令集扩充:当前解析器(_buildParser)包含new-tab/ntsplit-pane/spfocus-tab/ftmove-focus/mfmove-pane/mpswap-panefocus-pane/fpx-save等子命令——规格中设想的短格式命令别名(“new-tabntsplit-panesp”)已经落地,且split-pane的参数也从规格的--percent,-%演化成了取值范围0.01~0.99-s,--size浮点参数(第 271-278 行),并新增-D,--duplicate复制当前窗格;
  • terminal_parameters 大幅扩展:_addNewTerminalArgs 除了规格定义的-p/--profile-d/--startingDirectory与位置参数commandline,还增加了--sessionId--title--tabColor--colorScheme--suppressApplicationTitle/!--useApplicationTitle--appendCommandLine--inheritEnvironment/!--reloadEnvironment等长格式参数——这正是规格“长格式覆盖 profile 属性完全合理”论断的后续展开;
  • 会话支持落地:规格中标注为“依赖其他工作”的--session概念,在 AppCommandlineArgs.h 中体现为-w,--window(指定目标窗口)与GetTargetWindow()ValidateStartupCommands中还有“单一x-save命令时把目标指向当前窗口”的特判;
  • list-profiles/open-settings未出现在当前解析器中:从源码结构看,这两个规格的查询类命令没有被纳入当前_buildParser的子命令集合,属于规格中未保留下来的部分。

需要说明的是:规格是 2020-01-15 的草稿(文档头部last updated字段),它完整记录了设计动机与 1.0 时期的决策脉络;当前源码是其之后的演进状态。阅读规格时应把它当作“设计蓝图 + 决策档案”,而具体参数拼写以wt --help与当前源码为准。

潜在问题:转义、子系统选择与命令顺序

规格用大量篇幅记录了三个真实存在过的工程难题,这部分对实际使用者同样重要。

命令行转义

因为用;分隔命令,而命令行本身也可能含;,所以字面分号必须写作\;。更棘手的是 PowerShell 也用;分隔命令——在 PowerShell 里调用多命令wt,用户需要先给 PowerShell 转义、再给wt转义

  • wt new-tab ; split-pane在 PowerShell 中要写成wt new-tab `; split-pane
  • 含字面分号的版本则变成wt new-tab `; split-pane commandline \`; with \`; semicolons——先用`;对 PowerShell 转义分号,再用反斜杠对wt转义;
  • 另一种思路是用引号包裹分号:wt new-tab ';' split-pane "commandline \; with \; semicolons"

规格的结论是:这种行为在 PowerShell 下确实不舒服,但没有更痛的替代方案;熟悉 PowerShell 的用户能理解这种转义。同时引用了 @jantari 的建议:PowerShell 的--%(停止解析)操作符可以整体规避问题:

# wt.exe 仍需被 PowerShell 解析(它是 PATH 中的命令),但其后的内容原样传递 wt.exe --% cmd.exe ; split-pane --target-pane 0 -V -% 30 wsl.exe

/SUBSYSTEM:Windows还是/SUBSYSTEM:Console

Windows 上的应用要么链接为 Windows 子系统、要么为 Console 子系统,wt面临两难:

  • 若是Console应用:从命令行启动时 shell 立即回到前台,进程的控制台输出会与 shell 输出混排
  • 若是Windows应用:从开始菜单/运行对话框等非控制台上下文启动时,系统会自动创建一个控制台窗口——即使只想弹出自己的窗口,屏幕上也会短暂闪一下控制台。

Python 系工具通常同时发布python.exe(Console)与pythonw.exe(Windows)两个可执行文件来规避,但这会造成大量用户困惑(wtw.exe -d .vswt.exe /?各自“该用哪个”)。规格最终提议参照msiexec /?的做法:作为 Windows 子系统应用,MessageBox显示帮助文本。理由:比控制权返回 shell 混排更清晰、比闪控制台窗口更体面、且有现成的先例。这一点在源码中同样可见:ParseCommand 手工识别-?//?抛出CallForHelp,_handleExit 把 CLI11 的 stdout/stderr 输出收集进_exitMessage字符串并置_shouldExitEarly,由上层决定如何展示——而不是直接写控制台。

new-tab不是第一个命令时

wt.exe split-pane -V ; new-tab为例:未来或许可以假定这些命令作用于“当前 Windows Terminal 窗口”,但 1.0 不具备会话寻址能力(尤其在未附着到任何 Terminal 会话的 conhost 窗口里,根本找不到“当前会话”)。规格的结论是假定一条隐式new-tab先行执行以创建窗口,团队讨论后确认这是正确行为(引 @DHowett-MSFT 的论断:wt.exe无参数时本来就是隐式new-window/new-tab,不能收回这份易用性)。同时open-settings单独出现时不应隐含new-tab——只应打开用户所选的.json编辑器。

能力与风险自评(Capabilities)

规格对自身特性做了标准的能力维度自评,完整继承如下:

  • 可访问性:作为命令行特性,其可访问性基本取决于调用方环境(conhost.exe或 Windows Terminal 本身)暴露可访问性通知的能力,两者都已支持基本的可访问性模式;
  • 安全性:解析用户输入固有缓冲区长度、输入取值等担忧。所幸命令行经由winMainCommandLineToArgvW由操作系统处理并传入,但解析时仍应格外小心——当前实现中 ParseArgs 对-Embedding--from-toast等内部哨兵参数先行短路,避免内部调用被误解析,正是这种谨慎的体现;
  • 可靠性:无特殊担忧;
  • 兼容性:不回归任何既有行为;
  • 性能/功耗/效率:对启动时间等无明显影响。

未来展望(Future Considerations)

规格最后列出了一批依赖其他特性的前瞻设计,作为该设计空间的完整档案:

  • 附着到已有会话wt --session [some-session-id] [commands],让命令作用于其他已运行的窗口(如wt --session 0 cmd.exe在另一个窗口开新标签)。依赖 #2080 所述的“管理器进程”方案;
  • list-sessions:列出所有活跃的 Windows Terminal 实例及其会话 ID,输出格式与上面的--session兼容;
  • --elevated:请求以提权上下文启动进程,服务于 #632 的需求;
  • --file,-f configuration-file:从配置文件读取命令列表,实现用户故事 14 的可复用启动配置。处理“一整文件启动命令”时的语义假定是:文件中的第一个new-tab创建窗口,后续new-tab都在该窗口内建标签;
  • defaultConfiguration:曾有如 #756 的“默认以多标签/多窗格启动”的需求。设想在profiles.json中加入defaultConfiguration属性指向一个命令文件,窗口创建时像解析命令行一样解析它;若用户命令行显式给了文件,则忽略profiles.json中的值;
  • PowerShell 参数补全:调研Register-ArgumentCompleter,为wt参数提供自动补全;
  • 短格式命令别名:如wt ; sp less some-log.txt ; fp -t 0

值得一提的是,其中“短命令别名”一项已在当前源码中兑现(nt/sp/ft/mf/mp/fp,见 AppCommandlineArgs.cpp),而--session/--window也以演化后的形态存在(-w,--window+GetTargetWindow)。

小结

这篇 #607 规格的价值在于它完整展示了 Windows Terminal 命令行体系的设计全貌:用 14 个用户故事锚定需求,用“命令 + 参数”双段式语法解决多标签/多窗格编排的表达力问题,用分号分隔 +\;转义平衡可读性与安全性,用隐式new-tab守住无参数启动的易用性底线。规格中记录的技术决策——CLI11 解析、ActionAndArgs复用、启动动作逐条分发——都能在 src/cascadia/TerminalApp/ 与 src/cascadia/LocalTests_TerminalApp/CommandlineTest.cpp 中找到一一对应的实现与测试。对使用者而言,掌握new-tabsplit-pane及其参数、-p/-d组合与 PowerShell 下的转义规则,就足以覆盖绝大多数定制化启动场景;对研究者而言,这份规格加上当前源码,是理解 Windows Terminal 启动链路的最佳入口。

【免费下载链接】terminalThe new Windows Terminal and the original Windows console host, all in the same place!项目地址: https://gitcode.com/GitHub_Trending/term/terminal

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询