重装 Windows 本身并不费时间。真正折磨人的环节通常在系统装好以后:先下载浏览器,再找 Git、VS Code、压缩软件、终端、Docker、Node.js、Go、Python,接着处理 PATH、登录账号、导入配置。等桌面终于恢复到熟悉的样子,半天已经过去了。

以前我也会准备一个“新电脑软件清单”,重装后照着网页逐个下载。这个办法能用,但每次都要重新确认官网、点击安装程序,还容易漏掉那些平时不起眼、缺了又难受的小工具。

Windows 自带的 winget 可以省掉大部分重复劳动。它无法替你恢复所有软件配置,也不会备份项目和账号,但用来重新安装常用软件已经很方便。

本文以 Windows 11 为主。Windows 10 较新的版本也可以使用 WinGet。

WinGet export 命令帮助

先看看电脑里有没有 winget

打开 Windows Terminal 或 PowerShell,运行:

winget --info

能看到版本、日志目录和源信息,就可以继续。

也可以只看版本:

winget --version

如果提示找不到命令,先去 Microsoft Store 更新 应用安装程序(App Installer)。个别精简系统、Windows Sandbox 或被删掉商店组件的环境需要单独修复 WinGet。

正式操作前,建议更新一次软件源:

winget source update

先搜索一个常见软件测试连接:

winget search --id Git.Git -e

这里的 -e 表示精确匹配,避免同名或相似软件干扰结果。

重装前:把当前软件清单导出来

准备一个不会随着系统盘一起格式化的目录,例如移动硬盘、其他分区或网盘同步目录:

New-Item -ItemType Directory -Force D:\Backup\winget | Out-Null

然后导出:

winget export `
  --output D:\Backup\winget\packages.json `
  --accept-source-agreements

WinGet 会尝试识别电脑中已经安装的软件,并把能够匹配到的软件包写进 JSON 文件。

WinGet 导出软件清单

导出过程中出现几条警告很常见。有些软件是便携版,有些安装器没有留下足够清晰的包信息,还有些软件根本不在当前 WinGet 源中。这些项目无法自动写入清单,需要自己记一下。

导出后别急着关机,先用 VS Code 或记事本打开 packages.json 看一遍。卸载残留、临时工具、硬件厂商附赠软件通常没必要带到新系统里,可以直接删掉对应的 PackageIdentifier

要不要加 --include-versions

WinGet 支持把当前版本一起导出:

winget export `
  --output D:\Backup\winget\packages-with-versions.json `
  --include-versions `
  --accept-source-agreements

我不建议普通个人电脑默认固定所有版本。重装时,旧版本可能已经从源里下架,导入过程反而容易报错。

以下场景才更适合记录版本:

  • 项目明确依赖某一版工具链;
  • 新版软件存在已知兼容问题;
  • 需要还原一台构建机或测试机;
  • 团队希望复现同一套开发环境。

个人主力机通常安装最新版更省心。

重装后:一条命令批量恢复

系统安装完成并确认 WinGet 可用后,把之前的 JSON 文件复制回来,然后运行:

winget import `
  --import-file D:\Backup\winget\packages.json `
  --ignore-unavailable `
  --accept-package-agreements `
  --accept-source-agreements

几个参数的作用:

  • --ignore-unavailable:某个软件暂时找不到时继续处理后面的项目;
  • --accept-package-agreements:自动接受软件包协议;
  • --accept-source-agreements:自动接受软件源协议。

WinGet 当前会按顺序安装导入文件里的应用,所以软件多时要等一会儿。某些安装器会请求管理员权限,也可能弹出安装窗口,这不代表批处理失败。

导出的文件里如果保存了旧版本,而你只想装最新版,可以加:

--ignore-versions

完整写法:

winget import `
  --import-file D:\Backup\winget\packages-with-versions.json `
  --ignore-versions `
  --ignore-unavailable `
  --accept-package-agreements `
  --accept-source-agreements

我更推荐再留一份手写安装脚本

winget export 很适合抢救现有环境,不过导出的清单往往夹杂着很多“装过,但并不想长期保留”的东西。

更稳的办法是维护一份短小的 PowerShell 脚本,只记录每次重装都确定需要的软件。

新建 install-dev-tools.ps1

$ErrorActionPreference = "Continue"

$packages = @(
    "7zip.7zip",
    "Git.Git",
    "Microsoft.VisualStudioCode",
    "Microsoft.WindowsTerminal",
    "Microsoft.PowerToys",
    "voidtools.Everything",
    "Flow-Launcher.Flow-Launcher",
    "Docker.DockerDesktop",
    "GoLang.Go",
    "OpenJS.NodeJS.LTS"
)

foreach ($id in $packages) {
    Write-Host "`n==> Installing $id" -ForegroundColor Cyan

    winget install `
        --id $id `
        --exact `
        --source winget `
        --accept-package-agreements `
        --accept-source-agreements

    if ($LASTEXITCODE -ne 0) {
        Write-Warning "$id 安装过程返回了退出码 $LASTEXITCODE,请稍后检查。"
    }
}

Write-Host "`n基础软件处理完成。建议重启终端后检查 PATH。" -ForegroundColor Green

运行前可以先确认软件包 ID:

winget search vscode
winget search docker
winget search nodejs

执行脚本:

Set-ExecutionPolicy -Scope Process Bypass
.\install-dev-tools.ps1

这里把执行策略只改在当前 PowerShell 进程里,窗口关闭后不会继续生效。

为什么脚本里不直接写 Python 版本

Python、JDK 等工具经常需要同时保留多个版本。直接把它们和普通桌面软件混在一起,时间久了很容易失控。

我一般把工具分成三类:

类型 适合的管理方式
Git、终端、VS Code、压缩软件 WinGet
Python、Node.js、Java 的多版本环境 pyenv、uv、nvm、SDKMAN 或项目工具链
项目依赖 requirements.txtpyproject.tomlgo.modpackage-lock.json

WinGet 负责把“机器”搭起来,项目自己的依赖仍然留在项目里管理。

一张图看懂要备份哪些东西

flowchart LR
    A[旧系统] --> B[winget export 软件清单]
    A --> C[手写 PowerShell 安装脚本]
    A --> D[项目、密钥和个人配置]
    B --> E[重装 Windows]
    C --> E
    D --> E
    E --> F[winget import]
    E --> G[恢复配置和数据]
    F --> H[可用的开发环境]
    G --> H

WinGet 只负责其中一条线。下面这些内容必须单独处理:

  • Git 用户配置和 SSH 密钥;
  • VS Code 设置、插件与登录状态;
  • WSL 发行版和 .wslconfig
  • Docker 镜像、Volume 与本地数据库;
  • 浏览器配置、密码和扩展;
  • 项目源码、环境变量和私有证书;
  • 软件内部的配置目录。

WSL 环境比较重要的话,可以先阅读站内的 Windows 11 + WSL2 开发环境搭建全教程。那里单独讲了 WSL 的目录、systemd、网络和备份思路。

平时也可以用 winget 管理升级

查看可以更新的软件:

winget upgrade

更新全部可更新软件:

winget upgrade --all

不建议每次看到更新就无脑跑,尤其是 Docker Desktop、数据库客户端、编译器和生产相关工具。先看一眼列表,再决定是否升级,省得第二天打开项目才发现环境变了。

暂时不想升级某个软件

WinGet 支持 pin。例如阻止 PowerToys 被 WinGet 升级:

winget pin add --id Microsoft.PowerToys --blocking

查看当前固定项:

winget pin list

取消固定:

winget pin remove --id Microsoft.PowerToys

普通 pin 会让软件跳过 winget upgrade --all,blocking pin 的限制更强。软件自己的自动更新器仍有可能绕过 WinGet,所以关键工具最好同时关闭内部自动升级。

进阶:WinGet Configuration

软件清单只能描述“要安装哪些应用”。更完整的机器初始化还会涉及系统设置、开发功能和其他配置。

WinGet 已经提供了声明式配置能力,可以通过配置文件描述期望状态。常用命令包括:

winget configure show -f .\machine.dsc.yaml
winget configure validate -f .\machine.dsc.yaml
winget configure test -f .\machine.dsc.yaml
winget configure -f .\machine.dsc.yaml --accept-configuration-agreements

还可以尝试导出当前软件配置:

winget configure export --all -o .\machine.dsc.yaml

这套方式适合经常重建开发机、需要统一团队环境,或者要准备实验室电脑的人。个人电脑刚开始没必要一步到位。先维护好 JSON 和安装脚本,已经能解决八成麻烦。

运行别人发来的配置文件前一定要阅读全文。配置资源可能调用 DSC 模块甚至执行脚本,看到“一键配置”四个字就直接运行,很容易把省下来的十分钟换成一晚上的排错。

国内网络环境下常见的几个问题

1. 搜索一直转圈或源更新失败

先查看软件源:

winget source list

然后更新:

winget source update

源状态明显异常时,可以在管理员终端重置:

winget source reset --force
winget source update

2. 代理开着,winget 反而连不上

新版 WinGet 命令支持单次指定代理或禁用代理。例如:

winget search Git.Git --proxy http://127.0.0.1:7897

或者强制本次不走代理:

winget search Git.Git --no-proxy

端口要换成自己的实际端口。使用 Clash Verge Rev 时,还要留意系统代理、TUN 和终端环境变量是否各走各的。站内的 Clash Verge Rev + Clash Meta for Android 全平台安装配置攻略 可以作为补充。

3. 安装完成后命令仍然找不到

先关闭当前终端,再开一个新的。安装器修改 PATH 后,已经运行的 PowerShell 通常不会自动刷新环境变量。

仍然无效,再检查:

$env:Path -split ';'

以及:

Get-Command git -ErrorAction SilentlyContinue
Get-Command code -ErrorAction SilentlyContinue

4. 某些软件明明装了,导出时却匹配不到

这通常和软件在 Windows “已安装的应用”里留下的名称、发布者和版本信息有关。WinGet 需要把这些信息与软件源中的清单对应起来,匹配不上就无法可靠导出。

碰到这类软件,最省时间的办法是把包 ID 手动补进自己的 PowerShell 脚本,而不是反复折腾导出文件。

我的实际建议

重装前准备三个东西就够了:

  1. packages.json,用于快速恢复大部分软件;
  2. install-dev-tools.ps1,保存真正长期使用的核心工具;
  3. 一个单独的数据备份,保存项目、密钥、配置和 WSL 等内容。

以后安装一个软件时,也可以顺手问自己一句:下次重装我还会装它吗?答案确定,就把包 ID 加进脚本。犹豫的话先别加。

这样维护几个月以后,你会得到一份很诚实的个人软件清单。它比“程序员必装 100 款软件”有用得多,因为里面每一个工具都是你确实离不开的。

需要补充常用软件选择,可以继续看站内的 新电脑必装软件(程序员向);系统恢复后准备使用 AI 编程工具,则可以接着看 OpenAI Codex 安装与使用全指南。桌面整理部分还有一篇轻松些的 Windows 桌面别再堆图标了:几个不折腾的小改造

参考资料

本文命令按 2026 年 8 月的 WinGet 官方文档整理。命令选项可能随版本更新,批量执行前可通过 winget <command> --help 查看本机版本支持情况。