跳到主要内容

WinGet 基础

WinGet 是微软官方的 Windows 包管理器,一句话概括:用一行命令把软件装好、升好、卸干净,不用点"下一步"。

winget install Git.Git

以前装软件是「搜官网 → 找下载链接 → 下 exe → 装 → 勾掉「创建桌面快捷方式」→ 下一步 → 完成」。有了 winget 之后,上面那一整串就是一行命令,而且卸载、升级、批量重装也是一行。

本文为基础篇,目标是:装好 winget → 学会搜/装/看/升/卸 → 能一条命令配置完一台新机器。

本文内容对照 WinGet v1.29(客户端版本会随「应用安装程序」自动更新,用 winget --version 查看)。

目录​

  1. winget 是什么
  2. 安装与自检
  3. 核心概念:ID、源、包
  4. 搜索 search
  5. 查看详情 show
  6. 安装 install
  7. 已装列表 list
  8. 升级 upgrade
  9. 卸载 uninstall
  10. 下载离线包 download
  11. 命令与参数速查
  12. 实战:一台新机器的初始化脚本
  13. 常见问题

1. winget 是什么​

它由三部分组成​

部分说明
winget.exe 客户端你在终端里敲的那个命令,随系统自带
包索引(source)一堆描述「哪个软件、多少版本、从哪下载、哈希是多少」的清单文件
包仓库(repository)存放索引的服务,winget-pkgs 社区仓库 + 微软商店

关键认知:winget 自己不存任何软件,它只是一个「读清单 + 下载 + 调用安装器」的工具。真正装东西的是软件官方的安装器(exe / msi / msix)。这也是为什么 winget 装出来的软件和官网下载装出来的是同一个软件。

管理员权限的影响​

情况表现
普通 PowerShell 窗口装「需要管理员」的软件时,弹 UAC 让你确认;你若点了取消,安装就失败
以管理员身份运行的 PowerShell不会有 UAC 弹窗直接装上,但也意味着你在给整台机器装东西

新手常见困惑:「为什么我明明是管理员,winget 还要弹 UAC?」——因为 winget 默认是以用户身份运行的,安装器自己再提权。开一个管理员 PowerShell 就能跳过这一步。

和 Scoop / Chocolatey 的区别​

WinGetScoopChocolatey
出品方微软官方社区社区(商业公司维护)
仓库来源社区维护 manifest社区 + 官方 GitHub Releases社区 + 部分官方源
权限多数走官方安装器,常需 UAC默认装到用户目录,无需管理员安装器为主,常需管理员
适用想装「和官网一模一样的正式版」想装「命令行工具」并保持用户级干净企业批量管控(付费功能多)

一句话:装开发工具优先 Scoop(免管理员),装桌面软件优先 winget(和官网一致)。两个可以共存。


2. 安装与自检​

系统要求​

  • Windows 10 1809(build 17763) 及以上,或 Windows 11
  • Windows Server 2025 支持;Server 2019 / 2022 属于实验性支持

winget 从哪来​

它不是一个单独的软件,而是**「应用安装程序」(App Installer)**这个系统组件带出来的命令行客户端。系统自带,一般不用装。

打开「Microsoft Store」→ 搜索 应用安装程序 / App Installer → 更新到最新版本,就能拿到最新的 winget。

如果你的机器上压根没有(比如精简版系统、LTSC、刚装完还没登录过):

  1. 商店里搜 App Installer 安装;
  2. 或者手动注册一次(首次登录新系统时 winget 迟迟不出现,多半是这个原因):
Add-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe

自检三连​

winget --version # 版本号
winget --info # 完整信息:系统版本、源、协议、组策略、许可证链接
winget --help # 命令列表

winget --info 的输出值得看一眼——如果发现某个源不是你配的,说明电脑上有组策略(GPO)在管控 winget,公司电脑尤其要留意:

源
winget (默认) https://cdn.winget.microsoft.com/cache
msstore (默认) https://storeedgefd.dsx.mp.microsoft.com/v9.0

winget.exe 找不到?​

命令提示「不是内部或外部命令」时,加到 PATH:

  1. Win + R → 输入 shell:AppsFolder 回车;
  2. 找到「应用安装程序」→ 右键 →「创建快捷方式」,快捷方式会落在桌面;
  3. 右键该快捷方式 →「属性」→ 复制「目标」一栏的完整路径(通常在 C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\AppInstaller\winget.exe);
  4. 把这个目录加到「系统属性 → 环境变量 → 用户变量 → Path」。

每次更新「应用安装程序」后版本文件夹名里的哈希会变,所以更稳妥的做法是别手动加 PATH,而是去 Microsoft Store 更新组件。


3. 核心概念:ID、源、包​

包的 ID 长什么样​

winget search vscode

输出里每一行都有一个 ID:

名称 标识 来源 版本
Visual Studio Code Microsoft.VisualStudioCode winget 1.95.0
VSCodium Anysphere.VSCodium winget 1.95.0

ID 的格式是 发布者.应用名,全局唯一。Microsoft.VisualStudioCode 和 Anysphere.VSCodium 是两个完全不同的软件(前者是微软官方版,后者是 VSCodium 社区版)。

用 ID 安装比用名称可靠得多,原因:

  • 名称是「显示用」的,同一个软件在不同语言下可能不一样;
  • 名称可能重名,search code 会返回一堆结果;
  • ID 精确,脚本里不会因为搜索结果排序变化而装错东西。

直接敲 winget install vscode 也可以(winget 会自己去搜),但在脚本里必须用 ID + -e。

两个(实际是三个)默认源​

源名是什么注意
wingetWinGet 社区仓库(manifest 由社区贡献)主力源,绝大多数软件在这里
msstore微软商店ID 是一串大写字母数字(商店的 PFN),不需要 -e
winget-font社区字体仓库默认是「显式」源,必须 --source winget-font 才会被搜索到
winget source list # 看当前有哪些源

为什么会出现「找到多个」​

winget install chrome

如果 winget 源和 msstore 源里都有叫 Chrome 的东西,winget 会列出候选让你选。在脚本里这是致命的,所以要加 --source winget 限定。


winget search <关键词>

匹配范围是名称、ID、描述、moniker、标签的大小写不敏感子串。不支持通配符——写 winget search fire* 是搜不到 Firefox 的。

常用过滤参数​

参数作用例
--id只搜 IDwinget search --id Git.Git
--name只搜名称winget search --name "Visual Studio Code"
--moniker只搜 monikerwinget search --moniker chrome
--tag按标签过滤winget search --tag editor
--cmd / --command按「装完能敲的命令」搜winget search --command python
-s / --source限定源winget search vscode -s msstore
-n / --count限制条数(1–1000)winget search browser -n 10
-e / --exact精确匹配(区分大小写)winget search Git.Git --id -e
--versions直接列出所有可用版本winget search vscode --versions

三个特别实用的搜法​

① 按命令搜(最省事)

不知道包名只记得命令名时:

winget search --command rg # 谁提供了 ripgrep
winget search --command node

② 列出全部包

winget search -q ""

新版本必须显式给空查询字符串。PowerShell 里要转义引号:

winget search -q "`""

③ 只搜某个源

winget search "Visual Studio Code" -s msstore

5. 查看详情 show​

winget show --id Microsoft.VisualStudioCode

输出包含:发布者、简介、主页、许可证、安装器类型、依赖、可用版本、安装大小。

安装前拿不准「这玩意装到哪、有没有捆绑流氓软件、要多少空间」时,先 show 一下。

winget show --id Microsoft.PowerToys --versions # 所有历史版本

想看某个包「到底用哪条安装命令装我」,看仓库里的 manifest 原文最快,见进阶篇。


6. 安装 install​

三种指定目标的方式​

winget install vscode # 按查询串(winget 自己搜)
winget install --name "Visual Studio Code" # 按名称
winget install --id Microsoft.VisualStudioCode # 按 ID

推荐第三种,并加 -e:

winget install --id Microsoft.VisualStudioCode -e

-e(--exact)是精确匹配,区分大小写。它的真正价值在脚本里:确保不会因为将来仓库新增了重名包而行为变化。

一次装多个​

winget install Microsoft.VisualStudioCode Microsoft.PowerShell Git.Git

按顺序依次安装,不是并行。配新机器时很方便。

常用参数​

参数作用例子
-v / --version装指定版本(不给就装最新)--version 0.91.1
--scope安装范围--scope user
-a / --architecture架构-a x64 / -a arm64
--installer-type强制选某类安装器--installer-type zip
-l / --location装到指定目录-l "D:\Tools\PowerToys"
-h / --silent静默安装,不显示任何界面
-i / --interactive强制显示安装界面
--no-upgrade已装了就跳过(脚本幂等的关键)
--force忽略非安全类问题继续执行
--allow-reinstall已安装也强制重装
--uninstall-previous升级时先卸掉旧版本
--custom追加传给安装器的参数--custom "/LOG D:\log.txt"
--override直接覆盖安装器命令行--override "/quiet /norestart"
--skip-dependencies跳过依赖检查
--allow-reboot允许在需要时重启
-r / --rename重命名可执行文件(仅 portable)

一个能直接复制走的安装命令​

winget install --id Microsoft.VisualStudioCode -e --silent `
--accept-package-agreements --accept-source-agreements --disable-interactivity

这四个参数是写自动化脚本的标准配置,后面会详细解释。

许可证协议​

有些软件安装前会弹「是否同意许可协议」。交互式使用时点确认即可,脚本里加:

--accept-package-agreements # 接受软件本身的协议
--accept-source-agreements # 接受源(仓库)的使用条款

两个是分开的:--accept-package-agreements 只管软件自己的许可,不管仓库的条款。

日志​

winget install --id Git.Git -o D:\logs\git-install.log

不指定 -o 时日志默认在:

%LOCALAPPDATA%\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\DiagOutputDir\

winget --logs 直接打开这个目录。


7. 已装列表 list​

winget list # 所有 winget 能识别的已装软件
winget list --name "Code" # 按名称过滤
winget list --upgrade-available # ★ 只看「有新版可升」的

--upgrade-available 是最常用的一个:它只列出需要升级的包,不用自己肉眼比对。

--include-unknown 的意义​

winget list --upgrade-available --include-unknown

默认情况下,winget 只认自己仓库里有的包。手工装的、官网下载的、系统自带的,ID 对不上,winget 就不管它们。

加了 --include-unknown 之后,已经装在机器上、但仓库里找不到的包也会列出来,状态标记为「无升级 / 未知」。

  • 用它做软件资产盘点很好用(能看见机器上到底装了什么);
  • 但用 winget upgrade --all 时要小心:--all 会把能升级的全部升一遍,包含那些原本没被 winget 管理的包,需要先确认。

显示 ID 列​

winget list --name "Code" --source winget

list 默认只显示「名称 / 版本 / 可用版本」。遇到重名软件想看 ID 时,加上 -e 再看,或者直接去「应用和功能」对照。


8. 升级 upgrade​

winget upgrade # 交互式:列出所有可升级的,逐个问你
winget upgrade --all # ★ 全部升级,不再逐个询问
winget upgrade --id Git.Git -e # 只升一个

--all 的两个注意点​

  1. 它会升级所有「有新版且 winget 认识」的包,包含你从官网手工装的那批(只要 ID 能对上)。
  2. 加上 --accept-package-agreements --disable-interactivity 才是无人值守的完整形态。

「刚装完就提示有新版」​

这个现象很常见,原因基本是以下几种:

原因说明怎么办
预览版仓库里存在更高版本的预发布包winget show --id X 看版本号是否是带 -preview 之类后缀
索引没更新本地缓存的清单还是旧的winget source update 后再看
多源版本号不一样msstore 源的版本和 winget 源不一致winget upgrade --id X -s winget 限定源
装的是非最新版你用 --version 锁过版本winget list --id X 对比「已装 / 可用」
架构不对装了 x86,系统在跑 x64,两边版本号独立卸载重装正确架构

最快的诊断姿势:

winget list --id XXX # 看「已装」和「可用」两列差多少
winget show --id XXX # 看仓库里到底有哪些版本

9. 卸载 uninstall​

winget uninstall --id Git.Git -e
winget uninstall --name "Visual Studio Code" -e

行为和 install 一样:优先用 manifest 里声明的卸载信息(ProductCode / UninstallSwitch),能干净地卸掉。做不到时退回到调用软件自己的卸载器。

同样支持一次卸多个 ID。


10. 下载离线包 download​

不安装,只把安装器下载到本地:

winget download --id Microsoft.VisualStudioCode -d D:\installers
参数作用
-d / --download-directory下载目录(不给就下载到当前目录)
--skip-dependencies不下依赖
--skip-license跳过许可文件
--version / --architecture / --scope / --installer-type同 install

用途:给内网机器准备离线安装包、在服务器上装没有浏览器的软件。


11. 命令与参数速查​

命令总览(v1.29)​

命令作用别名
search搜索可安装的软件find
show查看包详情
install安装add
list列出已安装
upgrade升级
uninstall卸载remove
download只下载安装包
pin管理版本锁定
export导出已装列表
import按文件批量安装
source管理源
configure按 YAML 把机器配置到目标状态
repair修复损坏的软件fix
hash计算安装包 SHA256
validate校验本地 manifest
settings打开 settings.json
features查看实验性功能开关状态
error查错误码含义
completion生成 shell 补全脚本

全局参数​

这些参数任何子命令都能加:

参数作用
--info详细信息(含组策略)
--logs打开日志目录
--verbose详细日志
--nowarn屏蔽警告
--disable-interactivity禁止一切交互提问
--proxy本次执行使用的代理
--no-proxy本次执行不走代理
-? / --help帮助(每个子命令都能单独 --help)
--wait执行完等回车再退出(调试时用,脚本里千万别加)

winget error 是个被严重低估的功能:

winget error 0x8A150011

直接输出错误码的中文/英文说明。遇到看不懂的 0x8A1500xx,先敲这一条。


12. 实战:一台新机器的初始化脚本​

把基础命令组合起来,就是一份可复用的「装机脚本」。

最小可用版​

# winget-init.ps1 —— 新机器一键装环境
$ErrorActionPreference = 'Continue'

# 脚本标准四件套
$commonArgs = @(
'--exact'
'--silent'
'--accept-package-agreements'
'--accept-source-agreements'
'--disable-interactivity'
)

$packages = @(
'Microsoft.VisualStudioCode'
'Git.Git'
'Microsoft.PowerShell'
'Python.Python.3.12'
'NodeJS.LTS'
'7zip.7zip'
'Notepad++.Notepad++'
'Google.Chrome'
)

foreach ($pkg in $packages) {
Write-Host "==> installing $pkg" -ForegroundColor Cyan
winget install --id $pkg @commonArgs
if ($LASTEXITCODE -ne 0) {
Write-Warning "$pkg failed with exit code $LASTEXITCODE"
}
}

Write-Host "`nAll done." -ForegroundColor Green

为什么用 --exact 而不是 -e:PowerShell 的参数解析里 -e 可能被当成别的,--exact 更明确。

为什么加 --no-upgrade 可以做到真正幂等:见下面的进阶版。

幂等版(可以反复跑)​

# 已经装了就跳过
foreach ($pkg in $packages) {
winget install --id $pkg @commonArgs --no-upgrade
}

--no-upgrade 的语义是「如果已装过(哪怕版本旧),直接跳过,不做升级也不报错」。这让脚本可以每周定时跑,只补装缺失的软件。

升级全部​

winget upgrade --all `
--accept-package-agreements `
--disable-interactivity

备份一份已装清单​

winget export -o D:\backup\apps.json --include-versions

新机器直接导入:

winget import -i D:\backup\apps.json

细节(版本锁定、--ignore-versions、源优先级、脚本化注意事项)见进阶篇。


13. 常见问题​

现象原因处理
winget 不是内部或外部命令App Installer 没更新 / 不在 PATH更新 App Installer;或按第 2 节加 PATH
第一次用没反应,过一会儿才有首次运行要建索引正常,等 10–30 秒;或 winget source update
搜不到某软件仓库里确实没有只能手工装,或者自己写 manifest 提交(进阶篇)
搜到一堆重名多源都有加 -s winget 限定源
脚本里装错了软件用了名称而不是 ID改用 --id + --exact
装到一半 UAC 弹窗需要提权用管理员 PowerShell,或让脚本里已装的不重装
0x8A150011安装包哈希与 manifest 不符见进阶篇的哈希章节,不要随手加 --ignore-security-hash
0x8A150014没找到匹配的包ID 写错,或源里没有
0x8A150016匹配到多个包加 --id -e -s winget
0x8A150010没有适用于本机的安装器架构不对,或该包不支持你的系统
装完提示要重启正常存一下工作,重启
卸载不干净manifest 缺卸载信息走「设置 → 应用」手动卸
装完 PATH 里没有安装器没改环境变量新开一个终端窗口再试
winget list 里有但 uninstall 找不到多源同名补 -s 限定源
升完还是显示有新版本预览版 / 索引过期 / 源不一致见第 8 节

遇到看不懂的报错,第一反应应该是:

winget error 0x8A1500XX

下一步​