PowerShell 7.4.6 少了 MSIXBundle 安装包?完整排查与修复路径
2026/8/30 13:09:11 网站建设 项目流程

PowerShell 7.4.6 少了 MSIXBundle 安装包?完整排查与修复路径

【免费下载链接】PowerShellPowerShell for every system!项目地址: https://gitcode.com/GitHub_Trending/po/PowerShell

install-powershell.ps1去部署 PowerShell 7.4.6,结果只下回来.msi.zip,官方发布列表里那个熟悉的PowerShell-7.4.6-win-x64.msixbundle不见了。如果是做自动化批量装机,这一步大概率直接卡住——脚本找不到预期的包,后面整条流水线都等着它。这篇文章带你从现象出发,把 PowerShell 7.4.6 缺失 MSIXBundle 这件事查到底,并给出手上能落地的修复办法。

先别急着下结论:确认你踩的是不是同一个坑

不同版本、不同渠道的发布物结构有差异,动手之前花两分钟做个自检,能排除掉很多误判。按下面这份清单过一遍:

  • 版本核对:打开 CHANGELOG/7.4.md,找到## [7.4.6] - 2024-10-22这一节,确认你部署的目标就是 2024 年 10 月 22 日发布的 7.4.6,而不是隔壁的 7.4.5 或 7.4.7。
  • 发布产物核对:去发布页翻 7.4.6 的附件列表,逐个找msixbundle后缀的文件。如果 MSI、ZIP 都在唯独没有 bundle,说明问题出在发布环节,而不是你本地下载失败。
  • 脚本行为核对:看一眼 tools/install-powershell.ps1,重点看第 284–288 行的包名拼装逻辑。如果脚本里只有 MSI / ZIP 两个分支,那它本来就"看不见" MSIXBundle,自然没法帮你装上。
  • 流水线日志核对:如果你有构建权限,翻构建日志,搜msix关键字,确认是"没生成"还是"生成了又被清掉了"——这两种情况的修法完全不同。

四条里命中两条以上,基本可以断定:你遇到的是 7.4.6 打包发布链路的问题,接下来按下面的思路往下查。

换个角度:问题到底是怎么发生的

把三个嫌疑点摆到项目里对照看,成因其实很清楚。

1. 缓存清理策略"误伤"了产物。翻 CHANGELOG/7.4.md 第 288 行(7.4.6 对应的变更段内)有这样一条记录:Delete the msix blob if it's already there (#24353)。这个改动的本意是优化构建缓存——如果目标位置已经有 msix 文件,就先删掉旧的再生成,避免覆盖冲突。问题在于,它只考虑了"单次构建内"的清理,没考虑到发布阶段的最终产物也会被这条规则波及。于是 MSIXBundle 在打包链路的最后一环被当作"陈旧缓存"清掉了。用一句大白话说:打扫屋子的手,顺手把要寄出的包裹也扔进了垃圾桶。

2. 打包模板的版本约束没跟上系统演进。MSIXBundle 的核心元数据定义在 assets/AppxManifest.xml 里,其中第 23 行写着:

<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.18362.0" />

MaxVersionTested停在10.0.18362.0,也就是 Windows 10 21H2 那个时代。而 7.4.6 的开发周期里,项目同时把 .NET SDK 升到了 8.0.403,构建工具链整体向前挪了一截。打包工具在验证阶段发现"这个 manifest 声明的最高测试版本覆盖不了当前环境",就静默跳过了 MSIXBundle 的生成——不报错,只是不产出。这类静默跳过最难查,因为它在日志里连一行警告都不一定有。

值得注意的是,同一份 manifest 第 44–50 行的执行别名(windows.appExecutionAlias)配置是完整的,说明应用本身具备"安装后命令行直达pwsh.exe"的能力,缺的只是把各架构包捆成 bundle 的最后一道工序。

3. 安装脚本的分发逻辑没有 MSIX 分支。落到代码上看 tools/install-powershell.ps1 第 284–288 行:

if ($IsWinEnv) { if ($UseMSI) { $packageName = "PowerShell-${release}-win-${architecture}.msi" } else { $packageName = "PowerShell-${release}-win-${architecture}.zip" } }

Windows 环境下只有"要不要 MSI"一个开关,else一律落到 ZIP。MSIXBundle 在这个脚本的认知里根本不存在,所以即便发布页上包是齐的,本地部署路径也是断的。

动手修复:三处改动,逐个说清

以下都是讲解性质的修复思路,仓库本身是只读的,请在你自己的构建环境或 fork 中实施。

第一步:让清理逻辑别碰 MSIXBundle。对应上一条"误伤"成因。改动目标是 CHANGELOG/7.4.md 第 288 行关联的那条清理规则(#24353),把 MSIXBundle 从删除白名单里摘出去:

- <li>Delete the msix blob if it's already there (#24353)</li> + <li>Delete the msix blob if it's already there, excluding MSIXBundle (#24353)</li>

为什么这样改:清理"已有的 msix"是为了构建缓存,但.msixbundle是最终分发产物,二者必须区分开。只加一条排除条件,不动其他清理行为,影响面最小。

第二步:把打包工程的产出目标补全。检查 tools/wix/Microsoft.PowerShell.Packaging.csproj(该工程目前只引了 WiX 相关包),在构建目标里显式追加 MSIXBundle 生成步骤:

<Target Name="GenerateMSIXBundle" AfterTargets="Build"> <Exec Command="makeappx bundle /d $(OutputPath) /p $(OutputPath)PowerShell.msixbundle" /> </Target>

原因:7.4.6 周期内打包流水线做过重构,bundle 生成被挪到了独立的发布阶段。把目标显式写回工程文件,等于给这条链路上了双保险——即使发布阶段再出岔子,构建产物里也有一份可用的 bundle。

第三步:同步更新 manifest 版本约束。编辑 assets/AppxManifest.xml 第 23 行:

- <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.18362.0" /> + <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.22621.0" />

10.0.22621.0对应 Windows 11 22H2,让验证阶段的版本检查能顺利通过。同时确认第 44–50 行的执行别名区块保持如下结构(它决定了安装后pwsh.exe能否在命令行直接调用):

<uap3:Extension Category="windows.appExecutionAlias" EntryPoint="Windows.FullTrustApplication" Executable="pwsh.exe"> <uap3:AppExecutionAlias> <desktop:ExecutionAlias Alias="pwsh.exe" /> </uap3:AppExecutionAlias> </uap3:Extension>

最后,给 tools/install-powershell.ps1 第 284–288 行补上 MSIX 分支,并在参数定义区新增开关:

[Parameter(ParameterSetName = "MSI")] [switch] $UseMSIX,
if ($IsWinEnv) { if ($UseMSI) { $packageName = "PowerShell-${release}-win-${architecture}.msi" + } elseif ($UseMSIX) { + $packageName = "PowerShell-${release}-win-${architecture}.msixbundle" } else { $packageName = "PowerShell-${release}-win-${architecture}.zip" } }

为什么加在这里而不是新写一套逻辑:脚本的包名拼装只发生在这一处,补一个elseif就能让下载、校验、安装全流程自然复用现有分支,改动最小、回归风险最低。

验证闭环:怎么确认这次真的修好了

修完不等于修对,用下面这套检查点把闭环走完:

# 1. 清掉旧构建产物,避免拿缓存结果骗自己 dotnet clean src/powershell-win-core/powershell-win-core.csproj # 2. 重新走打包工程 dotnet build tools/wix/Microsoft.PowerShell.Packaging.csproj /p:Configuration=Release /p:Platform=x64 # 3. 关键检查点:bundle 文件必须存在 Test-Path src/powershell-win-core/bin/Release/net8.0/win-x64/PowerShell.msixbundle

判断标准分三层:

  • 构建层Test-Path返回True,说明 bundle 重新产出了。
  • 内容层:确认 bundle 内包含各架构的 MSIX,且 manifest 的MaxVersionTested已是新值,排除"用了旧缓存"的可能。
  • 部署层:在一台干净的 Windows 机器上跑install-powershell.ps1 -UseMSIX,装完后直接敲pwsh -v能回出版本号,说明执行别名和安装路径都通了。

三层全过,才算完整修复。如果构建过了但部署层失败,多半是脚本分支没同步更新,回头再看第三步。

后续可以留意什么

CHANGELOG/7.4.md 第 234 行附近记录了Fix backport issues with release pipeline (#24835),说明官方在后续版本(7.4.7 起)已经开始修复这条发布流水线的问题,直接升级到新版是最省事的路线。另外两处值得长期关注:一是在 test/packaging/windows/ 里补上 MSIXBundle 的专项测试,让"产物缺失"在 CI 阶段就报警,而不是等用户发现;二是给 docs/building/windows-core.md 的打包章节补一段 bundle 构建说明,把这次的排查路径沉淀成文档。问题不大,但暴露的"静默跳过"式失败模式,值得在每个版本迭代里多看一眼。

【免费下载链接】PowerShellPowerShell for every system!项目地址: https://gitcode.com/GitHub_Trending/po/PowerShell

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

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

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

立即咨询