
上周末帮家里一位经常重装系统的朋友做电脑交付装完系统后的第一件事不是去下载各种安装包而是打开终端敲了几条 winget 命令。看着他一脸不解的表情我想起自己刚接触包管理时的样子。WinGetWindows Package Manager是微软官方推出的命令行包管理工具可以把“打开浏览器搜软件、找官网、下载安装包、点安装、同意捆绑协议”这一整套流程压缩成一行命令。这篇文章我会把 WinGet 的下载方式、安装细节、初始化设置以及从搜索到批量升级的完整使用链路全部整理出来适合刚接触包管理的开发者也适合不想再被各种软件捆绑安装折腾的普通用户。1. 先从三个问题搞清楚 WinGet 到底解决了什么1.1 没有包管理器之前Windows 用户的日常有多痛回想一下没有包管理软件的日子装一个 Git要去官网找下载入口下载完双击 exe一路 Next中间还要小心别点到捆绑安装的垃圾软件。想更新一款软件得重新打开官网重新下载新版本把旧的卸载掉再装上配置可能就跟着丢了。更常见的情况是很多软件自带“自动更新”但这些更新往往伴随着弹窗、开机自启甚至偷偷装上全家桶。卸载更麻烦。控制面板里的“卸载程序”只是移除主体桌面快捷方式、注册表残留、AppData 里的缓存文件散落一地。时间久了C 盘空间越来越少软件越用越乱却说不清是哪个安装包惹的祸。WinGet 解决的就是这个层面的问题。它把软件包抽象成一个个有唯一 ID 的“源条目”搜索、安装、卸载、升级全部走同一条命令体系。装上它之后配一台新电脑的软件环境基本上就是端着茶杯看终端滚动。1.2 用手机应用商店来理解 WinGet 的工作模式你可以把 WinGet 理解成 Windows 生态里默认跑的“命令行版应用商店”。它背后连接的是一个软件仓库里面收录了成千上万款常用软件的元数据包括软件的唯一标识Package ID、版本号、安装包类型、下载地址、哈希值等。当你执行winget install 某个ID时WinGet 会去源仓库里找到对应的安装包信息校验完整性之后根据安装包的类型选择对应的安装策略。如果是 MSI 或 EXE 安装包它会尝试用静默参数执行安装如果是 MSIX 包则直接通过部署接口部署。整个过程并不需要你在浏览器里亲自操作。这个思路其实和吃外卖一模一样——你不需要知道饭馆的后厨在哪只需要在外卖平台上下单然后等骑手把饭送到门口。WinGet 就是这个“外卖平台”软件源里的包就是“后厨的菜单”。1.3 和微软商店比WinGet 的优势在哪里很多人会问Windows 不是自带 Microsoft Store 吗为什么还要用 WinGet两者分工不同而且可以互补。Microsoft Store 面向的是普通消费者收录的是经过商店认证的 UWP 应用和少量 Win32 应用界面友好、安装干净但覆盖面有限。WinGet 面向的是开发者、IT 管理员和喜欢折腾的终端用户收录范围更广很多传统桌面软件比如开发工具、终端模拟器、压缩软件在商店里可能找不到但 WinGet 仓库里有。更关键的是WinGet 是可脚本化的。你能把安装软件这件事写进一个 PowerShell 脚本里一键部署整个开发环境这在企业批量装机和个人重装系统时都非常实用。商店给你的是一个图形界面WinGet 给你的是一整套自动化入口。2. 装之前先确认四件事能省掉后面 80% 的排错时间2.1 系统版本WinGet 的硬门槛WinGet 可以运行在 Windows 10 180917763及更高版本以及 Windows 11 全系。理论上只要系统达到这个门槛就能装。查看自己系统的具体版本最快的方式是Win R输入winver回车弹窗里会显示版本号和内部版本号。如果你还在用更老的 Windows 7 或 Windows 8.1建议放弃 WinGet先把系统升级到至少 Windows 10 1809 再说。这不是势利而是 WinGet 依赖现代 Windows 的打包部署基础组件旧系统缺胳膊少腿强装上去问题一大堆。2.2 核心组件App Installer 的存在与版本WinGet 早就不是“一个安装包直接装完”的独立程序它的本体其实藏在App Installer这个系统组件里。App Installer 是微软商店里的一个应用包WinGet 的 CLI 入口就是它提供的。所以判断系统有没有 WinGet本质上是在判断 App Installer 的可用状态。我见过不少朋友把网上教程里的安装包下载下来双击却发现部署失败原因就是他们忽略了 App Installer 的版本太旧或者干脆被精简掉了。检查新版 App Installer 是否已存在的命令很简单winget --version如果终端返回了类似v1.7.xxxx的版本号说明你的系统里已经有可用的 WinGet 了而且版本越新功能和修复的 bug 越多。如果提示“找不到命令”说明系统里没有 App Installer或者它的版本老到不兼容。2.3 应用商店有没有被禁用由于 WinGet 最方便的安装渠道是 Microsoft Store安装前要确认商店没有被组策略或企业镜像禁用。尤其是在单位配发的电脑上管理员经常把商店整个锁掉这时候就算你下载了安装包也可能因为缺少商店相关的依赖服务而装不上。打开开始菜单搜一下“Microsoft Store”。如果能正常打开、能浏览应用列表就说明商店是活的。如果点击没反应或者打开后一直转圈优先去“设置 - 应用 - 可选功能”里看看商店相关服务有没有被关闭再不行就用后面提到的 GitHub 离线部署方式绕过商店。2.4 网络环境是否允许访问软件的官方下发端点WinGet 默认的源是官方软件源安装、更新源索引都需要访问全球网络。在一些实验性网络、企业内网里可能会遇到官方端点连接超时的情况。装之前最好用浏览器访问一下软件源所在站点的响应能力如果网络不稳定后面的每一步都会卡到怀疑人生。不过别慌这篇文章后面会讲到换源和离线安装的方案。总的来说网络问题不是 WinGet 的硬伤只是需要多一步配置。3. 三种下载安装方式对比总有一种能贴合你的网络条件3.1 方式一从 Microsoft Store 安装 App Installer最省心这是绝大多数普通用户应该选的路径操作难度最低依赖关系也最少。具体步骤打开 Microsoft Store。右上角搜索框里输入“App Installer”。找到微软官方发布的那一款发布者显示为 Microsoft Corporation点击获取或更新。等待安装完成打开终端验证winget --version能看到版本号就说明成功了。我推荐普通用户优先走这条路因为 Store 版本会自动跟随系统更新不用担心 WinGet 自身版本落后。而且 Store 会顺带把 WinGet 依赖的框架组件一起处理好省去手动装依赖的麻烦。3.2 方式二从官方发布仓库直接下载安装包适合能正常访问海外网络的情况如果网络环境能稳定访问海外资源可以直接从微软官方维护的发布仓库下载最新版本的安装包。这种方式不需要商店前提是网络可靠。操作过程大致如下进入到发布仓库的 Releases 页面在最新版本的 Assets 区域找到后缀为.appxbundle的文件这是 WinGet 主安装包同时下载同版本下的.cer证书文件。下载之后先安装证书Import-Certificate -FilePath .\你的证书文件.cer -CertStoreLocation Cert:\LocalMachine\TrustedPeople接着部署主包Add-AppxPackage -Path .\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.appxbundle -ForceApplicationShutdown安装完成后同样用winget --version验证。在实际操作中Add-AppxPackage经常因为依赖缺失而失败。WinGet 主包依赖 Visual C 运行库框架包VCLibs等组件遇到提示“缺少依赖”时先把这些框架包也一并下载按“框架包在前、主包在后”的顺序依次执行Add-AppxPackage。3.3 方式三离线部署包方案适合内网、断网环境企业内网、实验机房这类不允许联网的环境也可以用离线方式部署 WinGet。思路很简单准备一台能够联网的机器把 WinGet 主安装包以及所有依赖框架包全部下载到本地复制到目标机器上之后按照依赖倒序逐个部署。我实际跑过的离线部署顺序大致是安装 VC 运行库框架包VCLibs安装 .NET 或 WinUI 相关框架如果目标系统缺失最后安装 App Installer 主包这个方案不需要网络但在批量部署前最好先在一台干净的虚拟机里跑一遍确认你收集的依赖清单是完整的否则几十上百台机器一起报缺依赖现场很狼狈。3.4 三种方式怎么选场景推荐方式原因普通个人电脑商店可用Store 安装零门槛自动更新网络条件能访问海外资源Release 文件安装版本可控最新特性第一时间体验企业内网批量部署离线包方案不依赖外网可控性最强如果你拿不准自己属于哪种情况我的建议是无脑先试 Store不行再上 Release实在不行再离线部署。这三条路不存在谁比谁更高级只是适应不同环境。4. 装好别急着搜软件先把两处基础配置处理完4.1 把 WinGet 自身更新到最新版本刚装完的 WinGet 不一定是全通道最新版尤其是 Store 分发存在延迟。旧版本在搜索、安装新软件时会遇到兼容性问题。更新 WinGet 自身其实就是把 App Installer 这个包升级到最新版本winget upgrade --id Microsoft.DesktopAppInstaller -e很长一段时间里WinGet 升级自己会出现“升级源为自身导致冲突”这种灵异现象。如果上面这条命令报错先手动更新一下源列表winget source update然后再试一次升级命令。实在不行用前面的方式二直接手动装新版安装包覆盖升级。4.2 给网络不稳的用户配置一个可用的源WinGet 默认只启用一个官方源名字就叫winget。在境外网络环境下这个源的响应速度极快但如果是境内普通宽带访问官方源经常超时症状就是winget search半天没反应或者直接报“无法从源中检索信息”。查看当前启用的源winget source list如果你所在环境访问官方源不顺畅可以用国内高校维护的开源镜像站做替代或补充。添加一个镜像源的方法winget source add --name mymirror --type REST --arg https://mirror.example.edu.cn/winget注意--type REST表示这是一个 REST 协议源--arg后面跟的是镜像地址。加完之后用winget source list确认新源已经在列表里以后搜索时默认会同时查官方源和新源哪个响应快用哪个。有些同学喜欢把官方源直接 remove 掉只留镜像源。我个人不建议这么做因为镜像源的数据同步存在延迟某些刚发布的新版本可能在镜像上查询不到。保留官方源作为兜底配合网络加速手段使用才是稳定策略。4.3 合理开启实验性功能WinGet 有些高级能力需要手动在设置文件里开启实验性开关。设置文件位于用户目录下的%LocalAppData%\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\settings.json没有这个文件就手动创建一个。一个常见的配置示例{ experimentalFeatures: { experimentalMSIX: true, uninstall: true } }experimentalMSIX用来支持部分 MSIX 包的精细操作uninstall开关则是一些卸载增强命令的前置条件。新版本中不少功能已默认启用如果你发现某个命令提示“需要实验性功能”再回来打开对应开关即可。4.4 设置默认接受源与包协议WinGet 首次安装软件时会弹出一堆协议确认提示在交互式终端里一键确认并不麻烦但在脚本里就是天大的障碍。解决方案是统一加两个参数--accept-package-agreements --accept-source-agreements前者表示接受包本身的许可协议后者表示接受源仓库的服务条款。写脚本时只要把这两个参数加上就不会在协议确认处卡住。我自己习惯把它们写进一个自定义的安装函数里每次调用都自动带上省心得很。5. 常用命令清单从搜索到批量卸载一次说清5.1 搜索软件winget search想找一个软件但不知道它的确切 ID 时用搜索winget search vscode返回结果里Id列是最关键的信息它决定了后面所有操作的准确性。搜索结果通常包含多个相似项需要仔细区分发布者。比如搜git很可能出来好几个同名工具有的是 Git 官方客户端有的是第三方 GUI 外壳选错了等于装了个别的软件。精确匹配搜索的写法winget search --id Git.Git -e-e表示精确匹配输出只有一条记录的时候基本可以确认这就是目标软件。5.2 查看软件详情winget show搜索到 ID 之后在安装之前最好先看下详细信息winget show Git.Git输出会列出软件的版本、发布者、安装包类型、许可证、源代码地址等信息。这些信息能帮你判断这个包是不是你想要的版本渠道。比如有些软件同时有稳定版和预览版两个 IDshow一眼就能看清楚差异。加--versions参数还可以列出该软件在源里支持的所有历史版本winget show Git.Git --versions这在需要固定特定版本时非常有用比如公司内部代码仓库要求 Git 2.40.x 或更高版本你就可以精确指定。5.3 安装软件winget install安装是 WinGet 的核心功能基础命令winget install --id Git.Git -e实际安装时我通常会组合几个参数winget install --id Git.Git -e --source winget --scope user --silent--source winget强制指定从官方源安装避免歧义。--scope user按用户级安装对没有管理员权限的账户很友好。--silent静默安装不弹安装向导。默认情况下很多大型软件比如 Visual Studio、Office安装时会自动采用静默参数这一步对普通用户是透明的。但要注意并不是所有安装包都支持静默少数软件强制需要交互式安装界面这种时候把--silent去掉即可。安装完成后我习惯顺手验证一下git --version如果终端能正常响应版本号说明软件真正可用了。有些软件安装后需要重启才会加入 PATH遇到命令找不到别急着卸载先重新打开一个终端窗口再说。5.4 查看已安装软件winget list每次装机装到一半总会想知道某软件到底装了没有手速快一点直接用winget list --id Git.Git -e输出正常说明已安装输出为空说明未安装。如果想盘点整台机器上所有由 WinGet 管理的软件winget list这个命令会列出系统里大部分已知应用但请注意有些软件是自己写注册表项的WinGet 识别不到列表里看不到不代表没装。5.5 卸载软件winget uninstall卸载命令winget uninstall --id Git.Git -e卸载操作比安装更需要小心。有些软件卸载时会询问是否保留用户配置WinGet 的静默卸载默认会走软件的默认卸载策略配置可能会被一并清掉。如果你在意配置文件先手动打开软件的设置界面备份再执行卸载。少数顽固软件卸载不干净WinGet 卸载完成后安装目录和注册表项还会残留。遇到这种情况先用winget list确认主程序确实没了再手工清理空目录一般问题不大。5.6 升级软件winget upgrade查看所有需要更新的软件winget upgrade没错upgrade命令不加任何参数会列出所有可更新的包。全部更新winget upgrade --all如果某几个软件你不想更新比如大版本升级后可能出现兼容性问题新版本里支持“锁定”机制winget pin add --id Git.Git -e锁定之后upgrade列表里就不会再出现这个软件。解除锁定winget pin remove --id Git.Git -e我一般会把整个办公室常用的几个大型 IDE 全部 pin 住因为这类软件的自动大版本升级经常把同事辛苦调好的插件配置冲掉。6. 进阶玩法批量安装开发环境与配置迁移6.1 一个脚本解决新机器的初始化问题WinGet 最大的价值在于“可编排”。我写过一个很简陋但非常实用的批处理脚本每次拿到新电脑或者重装完系统先在 PowerShell 里跑一遍开发环境就齐了一大半。$apps ( Git.Git, Microsoft.PowerShell, Microsoft.VisualStudioCode, 7zip.7zip, Google.Chrome, Notepad.Notepad, Python.Python.3.12, OpenJS.NodeJS.LTS ) foreach ($app in $apps) { Write-Host 正在安装: $app -ForegroundColor Green winget install --id $app -e --accept-package-agreements --accept-source-agreements }这个脚本做的事情很简单定义了一个数组里面是所有要装软件的 ID然后循环执行winget install。关键是协议参数已经默认接受全程不需要人工干预。配合笔者的习惯我会在这个脚本前面加一段检查 WinGet 是否存在的逻辑if (-not (Get-Command winget -ErrorAction SilentlyContinue)) { Write-Host 未检测到 WinGet请先安装 -ForegroundColor Red exit 1 }这样即使在一台全新的裸机上执行脚本也能第一时间给出明确提示而不是抛出一大串红色的报错堆栈。6.2 用导出导入命令把软件清单从一台机器搬到另一台WinGet 从比较早的版本开始支持export和import可以把当前机器上通过 WinGet 安装的所有软件清单导出成一个 JSON 文件再到新机器上导入安装。winget export -o apps.json导出的 JSON 里记录了软件 ID、来源、版本等关键信息。到了新机器上执行winget import -i apps.json --accept-package-agreements --accept-source-agreementsWinGet 会逐条解析 JSON把缺失的软件安装上已经存在的软件会自动跳过。实际使用时有两个坑要提前知道。第一导出清单里如果包含 Store 来源的软件导入时有时候会提示来源不可用需要在命令后加--include-unknown之类的参数来处理第二版本信息如果锁定得过死后续软件更新后清单导入会匹配不到所以我一般只在同批次同型号的办公电脑之间做导入比如一班 30 台机器标准环境一次搞定。6.3 在无交互环境下的自动化保持良好的日志习惯脚本化运行最怕的就是中间失败却没有任何记录。我强烈建议在跑批量安装时把输出重定向到日志文件winget install --id Git.Git -e --accept-package-agreements --accept-source-agreements install.log 21这样即便半夜跑批第二天早上打开日志就知道哪一步卡了、哪个包失败了。排查时先看日志尾部再针对性重跑失败的那一个软件效率会高很多。7. 排错实战我踩过的高频问题与完整排查链路7.1 症状search 和 install 一直转圈最后报网络错误这是我见过最多的问题。第一次用 WinGet执行winget search终端卡住不动过一会儿提示无法从源中检索。排查路径我一般按顺序走# 第一步确认源列表状态 winget source list # 第二步主动触发一次源更新 winget source update # 第三步换个源搜索验证是不是官方源网络问题 winget search vscode --source mymirror如果换了镜像源能秒搜出来问题基本锁定在官方源的网络不可达。处理方案就是上面说的保留官方源添加一个响应快的镜像源日常使用 WinGet 时让它自己去选源即可。7.2 症状安装成功但软件无法启动这类问题的典型套路是终端显示“已成功安装”桌面上也能看到图标但点击后一直没反应或者立刻闪退。原因大概率出在静默安装参数上。某些软件本身就抵触静默安装WinGet 调用它的无人值守模式失败了但返回码是 0界面层就误判为成功。面对这种软件把命令行里的静默参数去掉改用交互式安装winget install --id 某个ID -e --interactive有些兼容性很差的软件WinGet 用系统自带的静默参数完全无法驱动这时我会直接放弃在 WinGet 层面解决改成从官网下载安装包手动装这是最务实的做法。包管理工具也不是万能钥匙。7.3 症状部署安装包时报“当前系统未安装应用商店”很多精简版 Windows 镜像或企业定制镜像把 Store 组件整个砍掉了。但 WinGet 的核心组件 App Installer 依赖的是商店基础设施哪怕你是用 Release 部署包手动安装也摆脱不了这个依赖。我的处理思路先试手动部署 Release 包如果在安装依赖框架包时提示缺少商店组件就说明系统镜像的商店被彻底削掉了。检查系统设置里是否有“应用商店”可选功能有的话先把商店组件加回去。如果公司政策禁止恢复商店那就彻底放弃 WinGet 这条路改用其他软件分发工具或脚本去解决同一问题。这个场景说明了一件事WinGet 虽然被包装成了一个独立工具但血统上它仍然是商店家族的一员绕不开商店基础组件的时候就别硬绕。7.4 症状卸载某软件时报“目录不是空文件夹”或者“另一个程序正在使用此文件”卸载 VSCode、Docker Desktop 这类深度依赖用户目录的软件时经常遇到残留文件锁死主程序定位表项。WinGet 的卸载只是调用了卸载程序的主体逻辑而子进程退出前可能还没来得及释放全部文件句柄。我的解决办法是分两步走关闭包括系统托盘在内的所有相关进程然后再执行一次winget uninstall --id 某个ID -e。如果还是失败手动删除残留目录一般是%LocalAppData%\Programs\...以及%AppData%\...下对应目录然后重试卸载。这里我要强调一个经验很多时候“卸载不干净”的锅其实不在 WinGet而是这些软件自身卸载器写得马虎。WinGet 只是把卸载命令转交给了卸载器卸载器都不肯好好干活工具层面再强大也没辙。7.5 症状突然提示 WinGet 自身版本过旧命令不可用WinGet 的很多高级命令会在背后请求源里的额外信息如果本地版本的协议和源服务端不匹配就会提示版本过旧或接口不支持。解决办法还是那句话先更新源列表再升级自身winget source update winget upgrade --id Microsoft.DesktopAppInstaller -e如果升级时提示“正在使用中”导致文件锁住关掉所有终端窗口再开一个新终端重试覆盖升级。这类问题没有更高效的办法只能保持 WinGet 新版本不断档。8. 把 WinGet 当成生活方式之后的一点心得用了一年多 WinGet最大的体会是“别把它当成一个软件把它当成你管理 Windows 软件环境的账本”。每次装了新软件它会帮你记住每次需要调整环境它会帮你拆卸每次大批量迁移环境它还能导出一份清单给你带着走。最后再分享一个小技巧在 PowerShell 的$PROFILE文件里把最常用的命令做成几个函数别名比如win代表winget upgrade --allins代表winget install --id。这样日常使用连完整的命令都不用敲效率直接上一个台阶。WinGet 也有它的局限性不是所有软件都能在仓库里找到也不是每个软件的静默参数都那么配合。但作为 Windows 生态里免费的、官方出品的包管理工具它已经是提升日常效率性价比最高的选择之一。希望这篇从下载到排错的完整梳理能让你在使用 WinGet 的路上少走几步冤枉路。