winget-cli 的 Update-WinGetPackage 命令详解:用 Microsoft.WinGet.Client PowerShell 模块批量升级已安装软件包
2026/9/20 14:59:02 网站建设 项目流程
  • 包管理器
  • CLI

【免费下载链接】winget-cli

WinGet is the Windows Package Manager. This project includes a CLI (Command Line Interface), PowerShell modules, and a COM (Component Object Model) API (Application Programming Interface).

项目地址:https://gitcode.com/gh_mirrors/wi/winget-cli
点击查看免费下载

Update-WinGetPackage 是 winget-cli 项目附带的 Microsoft.WinGet.Client PowerShell 模块中用于升级已安装软件包的核心 cmdlet。本文以该 cmdlet 的官方帮助文档为主体,结合模块源码、示例脚本与自动化测试,系统讲解其语法、全部参数、典型用法以及从 PowerShell 层到 WinGet COM API 的底层调用链,帮助读者在日常脚本与自动化场景中精准、安全地完成包升级。

命令概述(SYNOPSIS)

Update-WinGetPackage的职责是:在已安装的软件包中搜索匹配项,并从已配置的源(source)中安装匹配软件包的更新版本。它等价于winget upgrade命令行在 PowerShell 模块中的对应实现,适用于需要在 PowerShell 脚本中批量升级软件、或通过管道与其他 cmdlet 组合使用的场景。

命令在模块中的注册位置为 UpdatePackageCmdlet.cs,源码中通过[Cmdlet(VerbsData.Update, Constants.WinGetNouns.Package, ...)]注册,并提供了别名udwgp

[Cmdlet( VerbsData.Update, Constants.WinGetNouns.Package, DefaultParameterSetName = Constants.FoundSet, SupportsShouldProcess = true)] [Alias("udwgp")] [OutputType(typeof(PSInstallResult))] public sealed class UpdatePackageCmdlet : InstallCmdlet

从源码可以看出两个关键事实:命令的默认参数集是 FoundSet(即按查询条件搜索后升级),且声明了SupportsShouldProcess = true,因此完整支持-WhatIf-Confirm这类 ShouldProcess 公共参数。

语法(SYNTAX)

该 cmdlet 包含两个参数集,分别对应两种升级方式。

FoundSet(默认参数集):按搜索条件定位包

Update-WinGetPackage [-IncludeUnknown] [-Mode <PSPackageInstallMode>] [-Override <String>] [-Custom <String>] [-Location <String>] [-Log <String>] [-Force] [-Header <String>] [-AllowHashMismatch] [-Architecture <PSProcessorArchitecture>] [-InstallerType <PSPackageInstallerType>] [-Locale <String>] [-Scope <PSPackageInstallScope>] [-SkipDependencies] [-Version <String>] [-Id <String>] [-Name <String>] [-Moniker <String>] [-Source <String>] [[-Query] <String[]>] [-MatchOption <PSPackageFieldMatchOption>] [-WhatIf] [-Confirm] [<CommonParameters>]

GivenSet:直接给定包对象

Update-WinGetPackage [-IncludeUnknown] [-Mode <PSPackageInstallMode>] [-Override <String>] [-Custom <String>] [-Location <String>] [-Log <String>] [-Force] [-Header <String>] [-AllowHashMismatch] [-Architecture <PSProcessorArchitecture>] [-InstallerType <PSPackageInstallerType>] [-Locale <String>] [-Scope <PSPackageInstallScope>] [-SkipDependencies] [[-PSCatalogPackage] <PSCatalogPackage>] [-Version <String>] [-WhatIf] [-Confirm] [<CommonParameters>]

两者的差异集中在"如何确定要升级的包":

  • FoundSet:通过-Id-Name-Moniker-Source-Query-MatchOption等搜索条件在源中定位包;
  • GivenSet:通过-PSCatalogPackage(别名InputObject,位置 0)直接传入由Find-WinGetPackageGet-WinGetPackage产出的包对象,支持管道按值(ByValue)传入。

功能描述(DESCRIPTION)

命令会先扫描系统上已安装的软件包,再为匹配的 WinGet 包安装更新版本。默认行为要点如下:

  • 默认在所有已配置的源中搜索;
  • 所有基于字符串的搜索默认是不区分大小写的子串匹配
  • 不支持通配符
  • 可通过-MatchOption参数改变搜索匹配方式。

从引擎源码 InstallerPackageCommand.cs 的Update方法可以看到,升级路径与安装路径的关键差异在于搜索行为与目标目录:

var result = this.Execute( async () => await this.GetPackageAndExecuteAsync( CompositeSearchBehavior.LocalCatalogs, PSEnumHelpers.ToPackageFieldMatchOption(psPackageFieldMatchOption), async (package, version) => { InstallOptions options = this.GetInstallOptions(version, psPackageInstallMode); options.AllowUpgradeToUnknownVersion = includeUnknown; ... return await this.UpgradePackageAsync(package, options); }));
  • 升级使用CompositeSearchBehavior.LocalCatalogs(本地已安装目录)定位已安装包,而Install方法使用CompositeSearchBehavior.RemotePackagesFromRemoteCatalogs(远程目录中的包);
  • -IncludeUnknown会映射为InstallOptions.AllowUpgradeToUnknownVersion,决定是否允许升级到注册表中未记录版本的包;
  • 最终通过PackageManagerWrapper.Instance.UpgradePackageAsync(package, options)调用底层 WinGet COM API 完成升级。

示例(EXAMPLES)

官方帮助文档提供了 5 个典型示例,覆盖了绝大多数使用场景。

示例 1:使用查询字符串升级包

Update-WinGetPackage Microsoft.PowerShell

-Query位置参数(Position 0),因此无需写出参数名,直接传查询字符串即可。

示例 2:按包标识符(Id)升级

Update-WinGetPackage -Id Microsoft.PowerShell

按包标识符定位目标。注意:如果同一标识符存在于多个源中,必须补充额外的搜索条件(如-Source)来选中具体的那一个包实例

示例 3:按包名称升级

Update-WinGetPackage -Name "PowerToys (Preview)"

按包显示名称定位目标,名称含空格时需用引号包裹。

示例 4:升级到指定版本

Update-WinGetPackage Microsoft.PowerShell -Version 7.4.4.0

先按Microsoft.PowerShell执行查询搜索,再将搜索结果限定为版本7.4.4.0的包。

示例 5:升级所有可升级的包

Get-WinGetPackage | Where-Object IsUpdateAvailable | Update-WinGetPackage

通过管道将Get-WinGetPackage输出的包对象过滤出"存在可用升级"(IsUpdateAvailable属性为真)的项,再逐项升级。这是批量更新所有软件的标准写法。

模块自带的示例脚本 Sample_UpdatePackage.ps1 还补充了更多组合用法,可作为参考:

# 按名称升级 Update-WinGetPackage -Name powertoys # 按标识符 + 指定版本升级 Update-WinGetPackage -Id Microsoft.PowerToys -Version 0.15.2 # 静默模式升级 Update-WinGetPackage -Id Microsoft.PowerToys -Mode Silent # 强制升级 Update-WinGetPackage -Id Microsoft.PowerToys -Force

参数详解(PARAMETERS)

以下按官方帮助文档完整列出所有参数,并结合源码补充每个参数的默认值与底层映射。

-AllowHashMismatch

允许在安装程序或依赖项的 SHA256 哈希与 WinGet 包清单中记录的哈希不一致时仍然下载并安装该包。

Type: System.Management.Automation.SwitchParameter Parameter Sets: (All) Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

该参数定义在公共基类 InstallerSelectionCmdlet.cs 中,注释明确其为"跳过安装程序哈希校验"。仅在确认来源可信时使用,否则会带来安全风险。

-Architecture

指定安装包的处理器架构。可选值:

  • Default
  • X86
  • Arm
  • X64
  • Arm64
Type: Microsoft.WinGet.Client.PSObjects.PSProcessorArchitecture Parameter Sets: (All) Accepted values: Default, X86, Arm, X64, Arm64 Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

源码中该属性的默认值为PSProcessorArchitecture.Default。在引擎层,若传入非Default的架构,会清空InstallOptions.AllowedArchitectures并仅加入指定架构,从而约束安装程序选择。

-Custom

向安装程序传递额外的自定义参数。参数接受单个字符串;如需多个参数,可把它们都写进同一个字符串。字符串须符合安装程序期望的参数格式;若字符串包含空格,必须用引号包裹。该字符串会追加到包清单中定义的参数之后

Type: System.String Parameter Sets: (All) Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

-Force

强制运行安装程序执行升级(即跳过非安全相关的失败,继续执行)。

Type: System.Management.Automation.SwitchParameter Parameter Sets: (All) Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

该参数定义于 InstallCmdlet.cs,源码注释为"在非安全相关失败时继续执行"。

-Header

为 REST 源指定自定义 HTTP 请求头值。

Type: System.String Parameter Sets: (All) Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

-Id

指定要搜索的包标识符。默认执行不区分大小写的子串匹配。

Type: System.String Parameter Sets: FoundSet Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

-IncludeUnknown

当已安装包的版本未记录在注册表中时,允许对其进行升级(即升级到"未知版本")。

Type: System.Management.Automation.SwitchParameter Parameter Sets: (All) Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

该参数是UpdatePackageCmdlet自身独有的属性(不继承自基类),在引擎层映射为InstallOptions.AllowUpgradeToUnknownVersion

-InstallerType

一个包可能包含多种安装程序类型,用此参数选择要使用的安装程序。可选值:

  • Default
  • Inno
  • Wix
  • Msi
  • Nullsoft
  • Zip
  • Msix
  • Exe
  • Burn
  • MSStore
  • Portable
Type: Microsoft.WinGet.Client.PSObjects.PSPackageInstallerType Parameter Sets: (All) Accepted values: Default, Inno, Wix, Msi, Nullsoft, Zip, Msix, Exe, Burn, MSStore, Portable Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

-Locale

指定安装包的语言区域(locale),须使用 BCP 47 格式,例如en-US

Type: System.String Parameter Sets: (All) Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

-Location

指定包的安装目录。安装程序必须支持备选安装位置,否则该参数无效。

Type: System.String Parameter Sets: (All) Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

源码中Location属性(见 InstallCmdlet.cs)对相对路径做了特殊处理:若传入的不是绝对路径,会自动拼接当前 PowerShell 文件系统位置,即SessionState.Path.CurrentFileSystemLocation + "\" + value

-Log

指定安装程序日志文件的保存位置。值可以是完全限定路径或相对路径,且必须包含文件名,例如$env:TEMP\package.log

注意:并非所有安装程序都支持该属性。

Type: System.String Parameter Sets: (All) Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

-MatchOption

指定 WinGet 包查询的匹配方式。可选值:

  • Equals(完全相等)
  • EqualsCaseInsensitive(忽略大小写的完全相等)
  • StartsWithCaseInsensitive(忽略大小写的前缀匹配)
  • ContainsCaseInsensitive(忽略大小写的子串匹配)
Type: Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption Parameter Sets: FoundSet Accepted values: Equals, EqualsCaseInsensitive, StartsWithCaseInsensitive, ContainsCaseInsensitive Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

注意该参数仅属于 FoundSet 参数集。源码中其默认值为ContainsCaseInsensitive(见 FinderCmdlet.cs),与帮助文档"默认子串匹配"的描述一致。

-Mode

指定安装程序的运行模式。可选值:

  • Default
  • Silent
  • Interactive

并非所有安装程序都支持全部模式。

Type: Microsoft.WinGet.Client.PSObjects.PSPackageInstallMode Parameter Sets: (All) Accepted values: Default, Silent, Interactive Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

源码中Mode的默认值为PSPackageInstallMode.Default

-Moniker

指定要升级包的 moniker(别名标识)。例如Microsoft.PowerShell包的 moniker 是pwsh

Type: System.String Parameter Sets: FoundSet Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

-Name

指定要升级的包的显示名称。

Type: System.String Parameter Sets: FoundSet Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

-Override

覆盖传递给安装程序的既有参数。与-Custom(追加)不同,该字符串会替换包清单中定义的安装参数。参数接受单个字符串;多个参数写在同一个字符串中,含空格时必须用引号包裹。

Type: System.String Parameter Sets: (All) Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

-PSCatalogPackage

直接提供PSCatalogPackage对象。可通过Find-WinGetPackageGet-WinGetPackage命令获取该对象。

Type: Microsoft.WinGet.Client.Engine.PSObjects.PSCatalogPackage Parameter Sets: GivenSet Aliases: InputObject Required: False Position: 0 Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False

该参数仅属于 GivenSet 参数集,是唯一同时支持"按属性名"与"按值"管道输入的参数——这正是Get-WinGetPackage | Update-WinGetPackage管道链能够工作的机制基础。

-Query

指定一个或多个要搜索的字符串。默认在全部已配置的源中搜索;不支持通配符。命令会将提供的值与以下包清单属性进行比较:

  • PackageIdentifier
  • PackageName
  • Moniker
  • Tags

比较方式为不区分大小写的子串比较。

Type: System.String[] Parameter Sets: FoundSet Required: False Position: 0 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

源码中Query还带有ValueFromRemainingArguments = true(见 FinderCmdlet.cs),即允许将位置参数中剩余的所有字符串都归入查询词。

-Scope

指定安装程序的安装范围。可选值:

  • Any
  • User
  • System
  • UserOrUnknown
  • SystemOrUnknown

注意:指定的安装范围必须存在于 WinGet 包清单中。

Type: Microsoft.WinGet.Client.PSObjects.PSPackageInstallScope Parameter Sets: (All) Accepted values: Any, User, System, UserOrUnknown, SystemOrUnknown Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

源码中Scope的默认值为PSPackageInstallScope.Any

-SkipDependencies

指定不安装 WinGet 包依赖项。

Type: System.Management.Automation.SwitchParameter Parameter Sets: (All) Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

-Source

指定已配置的 WinGet 源的名称。不指定时搜索所有源。

Type: System.String Parameter Sets: FoundSet Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

-Id命中的包存在于多个源时,可通过该参数消除歧义。

-Version

指定要升级到的包版本。

Type: System.String Parameter Sets: (All) Required: False Position: Named Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False

-Confirm

在运行 cmdlet 前提示确认(别名cf)。

Type: System.Management.Automation.SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Accept pipeline input: False Accept wildcard characters: False

-WhatIf

显示如果 cmdlet 运行会发生什么,但实际不执行(别名wi)。

Type: System.Management.Automation.SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Accept pipeline input: False Accept wildcard characters: False

CommonParameters

该 cmdlet 支持所有 PowerShell 公共参数:-Debug-ErrorAction-ErrorVariable-InformationAction-InformationVariable-OutVariable-OutBuffer-PipelineVariable-ProgressAction-Verbose-WarningAction-WarningVariable。由于 cmdlet 声明了SupportsShouldProcess = true-WhatIf-Confirm也能正常工作。

输入与输出(INPUTS / OUTPUTS)

输入类型

以下类型可以通过管道按属性名(ByPropertyName)传入,其中PSCatalogPackage额外支持按值(ByValue):

  • System.Management.Automation.SwitchParameter
  • Microsoft.WinGet.Client.PSObjects.PSPackageInstallMode
  • System.String
  • Microsoft.WinGet.Client.PSObjects.PSProcessorArchitecture
  • Microsoft.WinGet.Client.PSObjects.PSPackageInstallerType
  • Microsoft.WinGet.Client.PSObjects.PSPackageInstallScope
  • Microsoft.WinGet.Client.Engine.PSObjects.PSCatalogPackage
  • System.String[]
  • Microsoft.WinGet.Client.PSObjects.PSPackageFieldMatchOption

输出类型

  • Microsoft.WinGet.Client.Engine.PSObjects.PSInstallResult

即每次升级都会输出一个PSInstallResult对象,便于脚本捕获升级结果(安装/升级状态、错误码等)做后续处理。

源码实现:从 cmdlet 到 COM API 的完整调用链

理解Update-WinGetPackage的底层原理,可以沿着模块的两层架构追踪:模块由Microsoft.WinGet.Client.Cmdlets(cmdlet 实现)与Microsoft.WinGet.Client.Engine(真实业务逻辑)两个项目组成(参见 README.md)。

  1. Cmdlet 层:UpdatePackageCmdlet.cs 在ProcessRecord中收集所有参数,构造InstallerPackageCommand并调用其Update方法。-IncludeUnknown-MatchOption-Scope-Architecture-Mode-InstallerType以字符串形式传入后由PSEnumHelpers转换为引擎层枚举。
  2. 引擎层:InstallerPackageCommand.cs 的Update方法以CompositeSearchBehavior.LocalCatalogs在本地已安装目录中定位包,构造InstallOptions(设置AllowUpgradeToUnknownVersionAllowedArchitecturesInstallerTypePackageInstallScope等),最终经InstallOperationWithProgress调用PackageManagerWrapper.Instance.UpgradePackageAsync(package, options),即 WinGet 的 COM API。
  3. 输出层:无论安装还是升级,成功后都会输出PSInstallResult(结果状态 + 错误码)。

这也解释了为何Update-WinGetPackage的参数与Install-WinGetPackage高度重合——两者共用 InstallCmdlet.cs(-Mode-Override-Custom-Location-Log-Force-Header)、InstallerSelectionCmdlet.cs(-AllowHashMismatch-Architecture-InstallerType-Locale-Scope-SkipDependencies)以及 FinderCmdlet.cs(-Id-Name-Moniker-Source-Query-MatchOption)三个公共基类,仅在"搜索本地已安装目录"与"升级而非安装"这一点上分道扬镳。

自动化测试中的验证

模块的 Pester 测试 Microsoft.WinGet.Client.Tests.ps1 覆盖了该 cmdlet 的两条核心路径:

It 'Update by Id' { $result = Update-WinGetPackage -Id AppInstallerTest.TestExeInstaller Validate-WinGetPackageOperationResult $result $expectedExeInstallerResult 'update' } It 'Update by Name' { $result = Update-WinGetPackage -Name TestPortableExe Validate-WinGetPackageOperationResult $result $expectedPortableInstallerResult 'update' }

测试先用Install-WinGetPackage安装测试包(如AppInstallerTest.TestExeInstaller与便携版TestPortableExe),再分别通过-Id-Name执行升级,并校验返回的PSInstallResult中安装器错误码与卸载器错误码均为 0。这说明"按 Id 升级"与"按 Name 升级"两条主路径都经过真实的安装器执行与结果校验,是可靠可复现的用法。

相关命令

  • Get-WinGetPackage:列出已安装的 WinGet 包,可与本命令通过管道组合实现"批量升级所有可升级包"(见示例 5)。
  • Uninstall-WinGetPackage:卸载已安装的 WinGet 包,构成包生命周期管理的完整闭环。

使用要点小结

  1. 默认搜索行为:字符串搜索不区分大小写、子串匹配、不支持通配符,需要精确匹配时使用-MatchOption Equals-MatchOption EqualsCaseInsensitive
  2. 消除歧义-Id在多源命中同一标识符时报错,需配合-Source或改用-Name/-Moniker精确指定。
  3. 脚本安全:批量升级前先用-WhatIf预览;关键操作可用-Confirm交互确认。
  4. 静默升级:自动化场景建议使用-Mode Silent,并可用-Log指定日志文件便于排障。
  5. 哈希校验:除非完全信任来源,不要轻易使用-AllowHashMismatch绕过安装程序哈希校验。
  • 包管理器
  • CLI

【免费下载链接】winget-cli

WinGet is the Windows Package Manager. This project includes a CLI (Command Line Interface), PowerShell modules, and a COM (Component Object Model) API (Application Programming Interface).

项目地址:https://gitcode.com/gh_mirrors/wi/winget-cli
点击查看免费下载

相关推荐

上一篇:CUE语言安装与配置指南
下一篇:LSPosed开源项目安装与配置指南

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

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

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

立即咨询