news 2026/9/7 14:37:01

OpenConsole 构建指南:从子模块初始化到 Windows Terminal 的 MSIX 打包部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenConsole 构建指南:从子模块初始化到 Windows Terminal 的 MSIX 打包部署

OpenConsole 构建指南:从子模块初始化到 Windows Terminal 的 MSIX 打包部署

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

本文围绕 doc/building.md 展开,完整讲解 OpenConsole(Windows Terminal 与 conhost 的共用仓库)的构建全流程:子模块初始化、PowerShell 与 CMD 两种构建方式、测试脚本、NuGet 依赖的版本管理机制,以及如何从命令行构建并部署 Terminal 的.msix包、处理DEP0700部署失败。读完后可在 Windows 上独立完成该仓库的构建、测试、调试与打包部署。

一、构建前准备:子模块初始化与代码格式化工具

仓库使用 git 子模块管理部分依赖。在首次构建前,务必先还原/更新子模块:

git submodule update --init --recursive

仓库根目录的 OpenConsole.slnx 既可以在 Visual Studio 中打开构建,也可以通过/tools目录下的便捷脚本从命令行构建。

如果使用 Visual Studio 开发,建议同时配置代码格式化(clang-format)。先按下面任一构建说明完成环境搭建,然后执行:

Import-Module .\tools\OpenConsole.psm1 Set-MsBuildDevEnvironment Get-Format

之后在 Visual Studio 中进入 Tools > Options > Text Editor > C++ > Formatting,勾选 "Use custom clang-format.exe file",并选择仓库中/packages/clang-format.win-x86.10.0.0/tools/clang-format.exe(点击复选框下方的 "browse" 浏览)。

从源码看,PowerShell 模块 tools/OpenConsole.psm1 通过vswhere定位 Visual Studio 自带的 clang-format(见 Invoke-CodeFormat),因此格式化能力与本机安装的 VS 版本绑定;XAML 文件则由 XamlStyler 处理(配置文件见 XamlStyler.json)。

二、在 PowerShell 中构建

推荐的 PowerShell 构建流程只有三步:

Import-Module .\tools\OpenConsole.psm1 Set-MsBuildDevEnvironment Invoke-OpenConsoleBuild

各步骤的作用(结合 tools/OpenConsole.psm1 源码):

  1. Import-Module .\tools\OpenConsole.psm1:导入项目 PowerShell 模块。注意该模块头部声明了#Requires -Version 7(OpenConsole.psm1#L1),即需要 PowerShell 7 及以上版本。
  2. Set-MsBuildDevEnvironment:通过VSSetup模块查找已安装的 Visual Studio 实例(要求带Microsoft.VisualStudio.Component.VC.Tools.x86.x64组件),再调用Enter-VsDevShell进入 VS 开发者 Shell 环境,把 MSBuild 等工具注入当前 PowerShell 会话(见 Set-MsbuildDevEnvironment)。它还会根据PROCESSOR_ARCHITECTURE自动映射架构:amd64 →x64、x86 →x86、arm64 →arm64
  3. Invoke-OpenConsoleBuild:先执行两次nuget.exe restore(分别还原 OpenConsole.slnx 和全局包清单 dep/nuget/packages.config),然后调用msbuild.exe OpenConsole.slnx,且任何额外参数都会原样传递给 msbuild(见 Invoke-OpenConsoleBuild):
# 示例:指定配置与平台 Invoke-OpenConsoleBuild /p:Configuration=Release /p:Platform=x64

模块共导出了以下函数(见 Export-ModuleMember),文档中列出的核心函数包括:

函数作用
Invoke-OpenConsoleBuild构建整个解决方案,可透传 msbuild 参数
Invoke-OpenConsoleTests运行测试,默认只运行单元测试
Start-OpenConsole从输出目录启动 OpenConsole.exe,默认运行 x64
Debug-OpenConsole启动 OpenConsole.exe 并附加默认调试器,默认 x64
Invoke-CodeFormat使用 clang-format 按仓库编码风格格式化所有 C++ 文件
Invoke-XamlFormat/Test-XamlFormat用 XamlStyler 格式化 / 校验 XAML 文件格式

其中Invoke-OpenConsoleTests的实现细节值得注意(源码):

  • 测试清单来自 tools/tests.xml,按unit/ft类型区分;不传参数时只跑type="unit"的单元测试;-AllTests跑全部,-FTOnly只跑功能测试,-Test host等可按名称精确选择单个测试组;
  • 单元测试直接在当前目录执行 TAEF 的te.exe;功能测试(ft)会通过Invoke-TaefInNewWindow新建的 OpenConsole 窗口中逐个运行;
  • 需要 UIA 测试或全量测试时,脚本会自动拉起dep\WinAppDriver\WinAppDriver.exe,测试结束后再停止它——所以 UIA 测试期间鼠标会被占用,不能移动;
  • 测试二进制的输出位置是bin\<Platform>\<Configuration>\,且x86平台在路径上会被映射为Win32

tools/tests.xml 中定义的测试组包括:hosttextBufferterminalCoreterminalApplocalTerminalAppunitSettingsModelunitControlinteractivityWin32terminaladaptertypestil(以上为 unit 类型),以及featureuiawinconpty(ft 类型)。

三、在 CMD 中构建:razzle 与 bcz

CMD 下的标准流程是:

.\tools\razzle.cmd bcz

razzle.cmd:开发者环境初始化

tools/razzle.cmd 仿照 Windows 内部构建系统的同名脚本,负责一次性搭建好命令行构建环境:

  • tools目录加入 PATH,使bczrunut等脚本随处可用;
  • 设置OPENCON(仓库根目录)与OPENCON_TOOLS环境变量;
  • dep\nuget加入 PATH,并先执行nuget restore OpenConsole.slnxnuget restore dep\nuget\packages.config,以便后续能用上 vswhere;
  • 定位 MSBuild:优先使用 PATH 中已有的 msbuild.exe;否则用 vswhere 查找,版本范围限定为[17.0,19.0),即同时兼容 VS 2022(17.x)与 VS 18 预发布版(见 razzle.cmd#L58);
  • 根据PROCESSOR_ARCHITECTURE设置ARCH/PLATFORM(AMD64 → x64,否则 x86/Win32),默认构建配置DEFAULT_CONFIGURATION=Debug
  • 支持.razzlerc.cmd个人环境脚本(不存在时自动创建),也接受dbg/rel/x86等参数调整默认配置。

脚本结束时会打印 "The dev environment is ready to go!"。如果找不到 MSBuild,可先在一个开发者 Shell(Developer PowerShell/Command Prompt for VS)中执行Import-Module .\tools\OpenConsole.psm1; Set-MsbuildDevEnvironment再运行 razzle。

bcz / bx / bz:构建命令族

tools/bcz.cmd 用于清理并构建解决方案,支持参数:

  • dbg:手动指定 Debug 配置构建;
  • rel:手动指定 Release 配置构建;
  • audit:手动指定 AuditMode 配置构建;
  • no_clean:构建前不清理(更快,但可能因残留产物导致意外的构建失败);
  • exclusive:只构建当前目录下的项目而非整个解决方案。

关键行为(bcz.cmd 源码):

  • Debug 整解构建时会自动附加/p:AppxBundle=false,跳过耗时的 appx 打包——想要.msix请用 Release 构建;
  • 构建命令始终带/p:GenerateAppxPackageOnBuild=false,防止构建 wapproj 项目时触发完整的 .msix 打包;
  • 构建前会先nuget.exe restore(可用环境变量_SKIP_NUGET_RESTORE=1跳过);
  • 构建结果决定任务栏进度提示:成功则清除进度,失败则闪烁红色状态。

tools/bx.cmd 则是"只构建当前目录项目、且不先清理"的快捷方式,其实现就是一行call bcz exclusive no_clean %*bcz exclusive依赖 tools/bx.ps1 来解析当前目录对应的.vcxproj项目名。

测试脚本

razzle 环境下还有配套的测试脚本(见 tools/README.md):

  • runut.cmd—— 运行单元测试;
  • runft.cmd—— 运行功能测试;
  • runuia.cmd—— 运行 UIA 测试;
  • runformat.cmd—— 用 clang-format 格式化所有 C++ 文件以匹配编码风格(提 PR 前应执行,否则 CI 会阻止合并)。

tools/runut.cmd 会把%TAEF%(razzle 中设置为packages\Microsoft.Taef.10.100.251104001\build\Binaries\%ARCH%\TE.exe)指向十余个单元测试 DLL 依次跑通,例如Conhost.Unit.Tests.dllConParser.Unit.Tests.dlltil.unit.tests.dllUnitTests_TerminalCore\Terminal.Core.Unit.Tests.dll等;其中SettingsModel.Unit.Tests.dll单独使用其目录下独立的te.exe运行(对应 tests.xml 中isolatedTaef="true"unitSettingsModel),并且任何参数都会透传给 TAEF,实现更细粒度的测试控制。

一个推荐的日常工作流(来自 tools/README.md):

bcz dbg && runut /name:*<name of test>*

<name of test>换成你正在开发的功能区域对应测试名(例如鼠标输入相关的MouseInputTest)即可只跑相关测试;不传/name参数则运行全部单元测试。

四、运行与调试

要在 Visual Studio 中调试 Windows Terminal:

  1. 在解决方案资源管理器中右键CascadiaPackage,打开属性;
  2. 在 Debug 菜单中,把 "Application process" 和 "Background task process" 都改为 "Native Only";
  3. 之后按F5即可构建并调试 Terminal 项目。

注意:你不能通过直接运行 WindowsTerminal.exe 来启动 Terminal。原因在于它是打包应用(packaged app),需要以 Appx 包身份注册后才能运行——这也是后文要介绍 MSIX 部署流程的原因。

五、配置类型(Configuration Types)

OpenConsole 有三种构建配置:

  • Debug
  • Release
  • AuditMode

AuditMode 是一个实验性模式,会启用来自 CppCoreCheck 的额外静态分析。这与 bcz.cmd 中audit参数把_LAST_BUILD_CONF设置为AuditMode的实现相互印证。

六、NuGet 依赖的版本管理

全局版本统一管理

本项目的大多数 NuGet 包引用集中在单一配置中,保证所有包有唯一的"权威版本"。该版本会在构建前由构建流水线、环境初始化脚本或 Visual Studio(视情况)还原。

权威版本号定义在 dep/nuget/packages.config。例如当前清单中锁定了Microsoft.Taef 10.100.251104001Microsoft.Windows.CppWinRT 2.0.250303.1Microsoft.UI.Xaml 2.8.4Microsoft.Windows.ImplementationLibrary 1.0.250325.1等原生包,以及Appium.WebDriverSelenium.WebDriver等用于 UIA 测试的管理包。多数 NuGet 包还带有.props/.targets文件,需要由每个消费项目导入;这些导入语句集中在两个文件里:

  • src/common.nugetversions.props
  • src/common.nugetversions.targets

以 src/common.nugetversions.props 为例,可以看到其中按包名硬编码了带版本号的导入路径,如packages\Microsoft.Windows.CppWinRT.2.0.250303.1\...packages\Microsoft.UI.Xaml.2.8.4\...。因此当某个全局管理的版本变化时,以上三个文件必须同步修改

本地版本包的批量更新

某些 NuGet 包引用(如Microsoft.UI.Xaml)必须通过 Visual Studio 的 NuGet 包管理器之外的方式来更新。可以使用下面的命令片段(其中sed依赖 WSL 环境):

git grep -z -l $PackageName | xargs -0 sed -i -e 's/$OldVersionNumber/$NewVersionNumber/g'

其中:

  • $PackageName是包名,例如Microsoft.UI.Xaml
  • $OldVersionNumber是当前使用的版本号,例如2.4.0-prerelease.200506002
  • $NewVersionNumber是要迁移到的版本号,例如2.5.0-prerelease.200812002

示例用法:

git grep -z -l Microsoft.UI.Xaml | xargs -0 sed -i -e 's/2.4.0-prerelease.200506002/2.5.0-prerelease.200812002/g'

使用本地 .nupkg 文件替代下载包

如果希望使用本地的.nupkg文件而不是下载的 NuGet 包,步骤如下:

  1. 打开根目录的 NuGet.Config,取消注释 "Static Package Dependencies" 那一行(当前仓库中是<!--<add key="Static Package Dependencies" value="dep\packages" />-->,即第 6 行的注释行);
  2. 创建文件夹/dep/packages
  3. 把你的.nupkg文件放入/dep/packages
  4. 如果你使用的版本与现有版本不同,还需要按上文"Updating Nuget package references"的方式更新引用。

顺带说明:NuGet.Config 还把globalPackagesFolderrepositorypath都指向仓库内的.\packages目录,并配置了TerminalDependencies私有包源——这正是构建脚本执行nuget restore时包会落到根目录packages\下的原因(例如前面 clang-format 与 TAEF 的路径)。

七、从命令行构建并部署 Terminal 包

构建 .msix

Terminal 以.msix形式捆绑,由CascadiaPackage.wapproj项目产出。在已经运行过tools\razzle.cmd的窗口中执行:

"%msbuild%" "%OPENCON%\OpenConsole.slnx" /p:Configuration=%_LAST_BUILD_CONF% /p:Platform=%ARCH% /p:AppxSymbolPackageEnabled=false /t:Terminal\CascadiaPackage /m

这个过程比较耗时,且只生成msix、不会安装它。要部署该包,可以用 PowerShell:

# 如果还没有做过的话: Import-Module .\tools\OpenConsole.psm1; Set-MsBuildDevEnvironment; # Set-MsBuildDevEnvironment 用于找到 makeappx 的路径,执行时间略长。 # 如果你一直停留在 powershell 中,最好还是执行它。 Set-Location -Path src\cascadia\CascadiaPackage\AppPackages\CascadiaPackage_0.0.1.0_x64_Debug_Test; if ((Get-AppxPackage -Name 'WindowsTerminalDev*') -ne $null) { Remove-AppxPackage 'WindowsTerminalDev_0.0.1.0_x64__8wekyb3d8bbwe' }; New-Item ..\loose -Type Directory -Force; makeappx unpack /v /o /p .\CascadiaPackage_0.0.1.0_x64_Debug.msix /d ..\loose\; Add-AppxPackage -Path ..\loose\AppxManifest.xml -Register -ForceUpdateFromAnyVersion -ForceApplicationShutdown

流程要点:先按名称(WindowsTerminalDev*)删除已注册的同名开发包;再用makeappx unpack把 msix 解包为松散(loose)目录;最后以松散布局的AppxManifest.xml注册安装。

也有对应的 cmd.exe 版本(本质上是调 PowerShell 执行同样的逻辑,作者注明是直接复制自.vscode\tasks.json):

@rem razzle.cmd 没有设置 WindowsSdkDir(vsdevcmd.bat 会花很多逻辑去找它),这里硬编码: powershell -Command Set-Location -Path %OPENCON%\src\cascadia\CascadiaPackage\AppPackages\CascadiaPackage_0.0.1.0_x64_Debug_Test;if ((Get-AppxPackage -Name 'WindowsTerminalDev*') -ne $null) { Remove-AppxPackage 'WindowsTerminalDev_0.0.1.0_x64__8wekyb3d8bbwe'};New-Item ..\loose -Type Directory -Force;C:\'Program Files (x86)'\'Windows Kits'\10\bin\10.0.19041.0\x64\makeappx unpack /v /o /p .\CascadiaPackage_0.0.1.0_x64_Debug.msix /d ..\Loose\;Add-AppxPackage -Path ..\loose\AppxManifest.xml -Register -ForceUpdateFromAnyVersion -ForceApplicationShutdown

从 VS 构建包时会直接生成松散布局并注册松散清单,跳过 msix 环节,因此 VS 的内循环实际上比上面这套命令行方式快得多。

2022 年的改进:bx + DeployAppRecipe

以下命令可以构建 Terminal 包并直接部署:

pushd %OPENCON%\src\cascadia\CascadiaPackage bx "C:\Program Files\Microsoft Visual Studio\2022\Preview\Common7\IDE\DeployAppRecipe.exe" bin\%ARCH%\%_LAST_BUILD_CONF%\CascadiaPackage.build.appxrecipe popd

bx只构建 Terminal 包,其关键作用是生成CascadiaPackage.build.appxrecipe文件;构建完成后,DeployAppRecipe.exe就能像 Visual Studio 那样以松散布局部署。需要注意的是,这种方式无法利用 Visual Studio 的 FastUpToDate 检查——cppwinrt 在确认"无需重建"之前会做大量工作,因此整个包的构建明显更慢。

八、疑难排查:DEP0700 注册失败

偶尔在 VS 中部署时会出现如下错误:

DEP0700: Registration of the app failed. [0x80073CF6] error 0x80070020: Windows cannot register the package because of an internal error or low memory.

从源码仓库的经验记录看,这往往是因为OpenConsoleProxy.dll被其他 terminal 包实例锁定。在 PowerShell 中执行等效命令可以拿到更多信息:

Add-AppxPackage -register "Z:\dev\public\OpenConsole\src\cascadia\CascadiaPackage\bin\x64\Debug\AppX\AppxManifest.xml"

输出中会提示类似NOTE: For additional information, look for [ActivityId] dbf551f1-83d0-0007-43e7-9cded083da01 in the Event Log or use the command line Get-AppPackageLog -ActivityID ...,照做即可:

Get-AppPackageLog -ActivityID dbf551f1-83d0-0007-43e7-9cded083da01

日志会给出大量信息。典型的根因是平台无法删除打包 COM 条目,关键行形如:

AppX Deployment operation failed with error 0x0 from API Logging data because access was denied for file: C:\ProgramData\Microsoft\Windows\AppRepository\Packages\WindowsTerminalDev_0.0.1.0_x64__8wekyb3d8bbwe, user SID: S-1-5-18

拿到该路径后执行:

sudo start C:\ProgramData\Microsoft\Windows\AppRepository\Packages\WindowsTerminalDev_0.0.1.0_x64__8wekyb3d8bbwe

(用sudo,因为该路径受权限锁定。)进入其中的PackagedCom文件夹,用 File Locksmith(或 Process Explorer)检查OpenConsoleProxy.dll的占用情况,并且建议直接以管理员身份重新启动它——这会列出几个挂着的 terminal 进程,把它们全部结束。之后即可正常部署。

九、小结:推荐的完整构建闭环

综合本文与 tools/README.md,一个完整的开发验证闭环是:

  1. bcz:清理并构建解决方案;
  2. opencon:启动刚构建出的 console(继承 razzle 环境变量,宏脚本可直接用);
  3. testcon(在新窗口中):跑全部测试;
  4. runformat:格式化代码。

全部通过后,你的改动就具备了提 PR 的条件。整条链路的底层支撑是:tools/OpenConsole.psm1(PowerShell 侧)、tools/razzle.cmd+bcz/bx/run*.cmd(CMD 侧)、tools/tests.xml(测试清单)与dep/nuget/packages.config+src/common.nugetversions.props/.targets(依赖版本管理),阅读这些文件可以快速定位任何构建问题的来源。

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 14:36:38

51单片机光照强度显示程序:BH1750与LCD1602实战解析

简介&#xff1a;51单片机光照强度显示程序是一份适合嵌入式入门开发者与电子爱好者的完整工程&#xff0c;解决如何通过51单片机读取光照传感器信号&#xff0c;并借助LCD1602液晶屏实时显示环境光照强度的问题。程序涉及ADC模数转换、I2C总线通信、液晶驱动时序控制等多个知识…

作者头像 李华
网站建设 2026/9/7 14:35:17

MaaFgo v1.2升级指南:稳定、可控、可复用的自动化挂机工具

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 14:34:49

AI女友产品拆解:从大模型到情感陪伴系统的技术架构与落地实践

我一直觉得&#xff0c;希腊神话里皮格马利翁的故事&#xff0c;是整个赛博时代最好的隐喻。那个国王雕刻了一尊少女像&#xff0c;日复一日地凝视她、和她说话&#xff0c;最终爱上了自己的作品。到了今天&#xff0c;我们把雕像换成了大模型生成的一段段对话&#xff0c;把雕…

作者头像 李华
网站建设 2026/9/7 14:33:18

OneDrive本地同步配置与无法登录卸载安装排障指南

你电脑里的OneDrive&#xff0c;到底是用来存东西的&#xff0c;还是只会占着任务栏图标给你添堵的&#xff1f;这段时间我帮不少同事和朋友处理过OneDrive的同步问题&#xff0c;发现大多数人根本分不清自己的文件是在云端还是本地。这个标题问的其实就是一件很基础又很实用的…

作者头像 李华