
1. 为什么 WSL 的安装位置值得你花时间折腾很多人第一次装 WSL 都是无脑下一步等用了一年半载C 盘红了才想起来查它到底装在哪。WSL 默认把整个发行版塞进%LOCALAPPDATA%\Packages\下面这个路径跟着系统盘走系统盘一满WSL 启动变慢、Docker 拉镜像失败、编译大项目直接卡死问题全来了。我自己就踩过这个坑一台 512G 的笔记本C 盘只剩 8G 的时候wsl --shutdown都要等半分钟apt install直接报磁盘空间不足。这篇内容就是解决这个问题的先教你准确查出 WSL 当前装在哪再把它完整迁移到自定义路径比如 D 盘、外接 SSD 或者专门的数据盘。适合三类人看——C 盘快满的、想把开发环境和系统盘分离的、以及准备换更大硬盘需要整体搬迁的。整个过程不需要重装系统也不需要重新配置开发环境迁移完你的 Ubuntu、Docker、CUDA、conda 环境全都原样保留。需要提前说清楚一点WSL 分 WSL1 和 WSL2两者的存储机制完全不同。WSL1 是文件系统层面的映射迁移逻辑简单WSL2 是基于虚拟磁盘ext4.vhdx的迁移本质上是搬这个虚拟磁盘文件再重新注册。现在绝大多数人用的都是 WSL2所以下面以 WSL2 为主线讲WSL1 的情况会单独提一句。2. 先搞清楚你的 WSL 到底装在哪、是什么版本2.1 一条命令确认版本和发行版名称动手之前必须先确认两件事你用的是 WSL1 还是 WSL2以及发行版的准确名称。打开 PowerShell 或 CMD执行wsl -l -v输出大概长这样NAME STATE VERSION * Ubuntu-22.04 Running 2 docker-desktop Running 2这里的NAME就是后面所有命令要用的关键标识大小写和连字符都要一模一样写错了会提示找不到发行版。带*的是默认发行版。VERSION是 2 就说明是 WSL2走虚拟磁盘迁移方案。如果你只看到一堆乱码或者中文名先执行wsl --set-default-encoding utf8之类的编码调整或者直接在 Windows Terminal 里跑避免中文发行版名带来的路径问题。我建议迁移前把发行版名改成纯英文比如Ubuntu-22.04后面操作省心很多。2.2 找到虚拟磁盘文件的真实路径WSL2 的每个发行版对应一个ext4.vhdx文件默认位置在C:\Users\你的用户名\AppData\Local\Packages\发行版包名\LocalState\ext4.vhdx发行版包名不是发行版名而是类似CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc这样的包标识。手动去翻很麻烦用注册表查最快。在 PowerShell 里执行Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | ForEach-Object { $distro (Get-ItemProperty $_.PSPath).DistributionName $basePath (Get-ItemProperty $_.PSPath).BasePath Write-Output $distro $basePath }输出会直接告诉你每个发行版的BasePath那个目录里就躺着ext4.vhdx。你也可以用更土但更直观的办法打开文件资源管理器地址栏输入%LOCALAPPDATA%\Packages按修改时间排序最近用过的那个文件夹基本就是你的 WSL。提示查路径的时候先把 WSL 关掉wsl --shutdown否则 vhdx 文件被占用你既看不到准确大小也没法复制。2.3 看一眼这个文件到底有多大知道路径后右键ext4.vhdx看属性或者用命令Get-Item C:\Users\你的用户名\AppData\Local\Packages\...\LocalState\ext4.vhdx | Select-Object Length这个数字很关键。WSL2 的 vhdx 是动态扩展的你删了文件它不会自动缩小所以经常出现实际用了 20Gvhdx 却有 80G的情况。迁移前心里有数才能规划目标盘的空间。如果发现虚高得离谱可以先在 WSL 里执行sudo fstrim -av回收一下再关机能省不少复制时间。3. 迁移方案怎么选导出导入 vs 直接搬文件3.1 两种主流方案的本质区别迁移 WSL2 有两条路我先把结论摆出来推荐用wsl --exportwsl --import的官方方案直接复制 vhdx 文件再改注册表的路子虽然快但坑多。对比项导出导入方案直接搬 vhdx 方案操作复杂度中等命令清晰低但需改注册表数据安全性高导出文件是完整备份中复制中断可能损坏是否保留原发行版导入后可选择删除需手动注销磁盘占用迁移期间双份占用单份但需临时空间适用场景绝大多数情况磁盘空间极度紧张时默认用户保留需手动配置自动保留导出导入的核心逻辑是把整个发行版打包成一个 tar 文件这个 tar 是自包含的包含所有文件、配置、用户数据。然后在目标位置重新导入WSL 会在新路径下生成全新的 vhdx。好处是过程可回滚——只要 tar 文件还在随时能恢复。直接搬 vhdx 的逻辑是关掉 WSL把 vhdx 剪切到新位置然后修改注册表里的BasePath指向新目录。快是快但注册表改错一个字符发行版就启动不了而且没有中间备份。3.2 为什么我强烈建议走导出导入说个真实案例。我有个朋友图快直接剪切 vhdx 到移动硬盘结果复制到 90% 的时候硬盘接触不良断了vhdx 文件损坏里面两年的开发环境全没了最后只能重装。导出导入方案虽然多花点时间但 tar 文件是顺序写入的中途失败重来就行不会破坏源数据。另一个原因是跨盘符、跨文件系统的兼容性。vhdx 直接搬到 exFAT 格式的移动硬盘上WSL 可能识别不了因为 exFAT 不支持 vhdx 需要的某些特性。而 tar 文件是普通文件放哪都行导入时再生成 vhdx 到 NTFS 分区即可。还有一点导出导入天然支持版本升级和重命名。你可以在导入时给发行版起个新名字比如从Ubuntu-22.04改成Ubuntu-dev直接搬文件就做不到。3.3 什么情况下才考虑直接搬文件只有一种情况值得考虑直接搬目标盘和源盘在同一个物理磁盘上且你极度在意时间且 vhdx 文件不大比如 20G 以内。即便如此我也建议先wsl --export做个备份再搬双保险。至于 WSL1 用户情况简单得多——WSL1 的根文件系统就是%LOCALAPPDATA%\Packages\...\LocalState\rootfs这个普通目录直接剪切整个rootfs文件夹到新位置再改注册表BasePath即可没有 vhdx 那些事。但现在还在用 WSL1 的人应该很少了。4. 完整迁移实操从导出到导入的每一步4.1 迁移前的准备工作清单正式动手前按这个清单过一遍能避免 90% 的意外关闭所有 WSL 相关进程不只是终端Docker Desktop、VS Code 的 WSL 远程连接、PyCharm 的 WSL 解释器都要关掉。执行wsl --shutdown后再用任务管理器确认没有vmmem或wslservice残留。确认目标盘有足够空间tar 文件大小约等于 vhdx 实际使用量导入后新 vhdx 又要占一份所以目标盘至少要有实际数据量 × 2的余量。比如你 WSL 里实际用了 40G目标盘至少留 100G。目标路径用纯英文、无空格比如D:\WSL\Ubuntu-22.04别用D:\我的开发环境\空格和中文在某些命令解析时会出问题。备份重要数据虽然导出导入很安全但涉及磁盘操作养成备份习惯。代码推到远程仓库数据库导出成 sql 文件。记下默认用户名导入后默认用户会变成 root需要手动改回来。先在 WSL 里执行whoami记下你的用户名。注意如果你在 WSL 里跑了数据库、Redis 这类有状态服务迁移前务必先停服务、做数据落盘别让数据卡在内存里。4.2 第一步导出为 tar 文件假设你的发行版叫Ubuntu-22.04打算把 tar 临时放在D:\WSL\backup# 先彻底关闭 wsl --shutdown # 创建目标目录 mkdir D:\WSL\backup mkdir D:\WSL\Ubuntu-22.04 # 导出注意路径用反斜杠或双引号包裹 wsl --export Ubuntu-22.04 D:\WSL\backup\ubuntu2204.tar导出过程没有任何进度条终端会卡住不动这是正常的别以为死机了。40G 的数据大概要 5 到 15 分钟取决于磁盘速度。判断是否还在跑可以看任务管理器里wsl.exe或tar进程的磁盘读写。导出完成后去目标目录确认 tar 文件存在且大小合理。如果只有几 KB说明导出失败了检查发行版名是否写对。4.3 第二步注销原发行版先别急这一步很多人会紧张其实注销只是从 WSL 的注册表里移除记录不会删除你的 tar 文件。但为了保险我建议先导入成功、验证没问题之后再回来注销原发行版。如果你空间紧张必须先注销腾地方那就执行wsl --unregister Ubuntu-22.04执行后原 vhdx 会被删除C 盘空间立刻释放。但此时你只有 tar 文件这一个备份了务必确认 tar 完整。4.4 第三步导入到自定义路径这是核心步骤命令格式是wsl --import 新发行版名 安装目录 tar文件路径 --version 2实际执行wsl --import Ubuntu-22.04 D:\WSL\Ubuntu-22.04 D:\WSL\backup\ubuntu2204.tar --version 2几个关键点安装目录是目录不是文件路径WSL 会在这个目录下生成ext4.vhdx。--version 2明确指定用 WSL2不加的话可能默认成 WSL1。新发行版名可以和原来一样也可以不一样。如果原来的还没注销名字不能重复得先注销或起个新名。导入同样没有进度提示耐心等。完成后执行wsl -l -v应该能看到新发行版状态是 Stopped。4.5 第四步恢复默认用户关键易漏步骤导入后第一次进入 WSL你会发现提示符变成了root主机名因为wsl --import默认把默认用户设成了 root。改回来的方法# 进入 WSL wsl -d Ubuntu-22.04 # 编辑 wsl.conf sudo nano /etc/wsl.conf在文件里加上[user] default你的用户名保存退出然后在 PowerShell 里执行wsl --shutdown再重新进入用户就恢复成你自己了。如果你忘了原来的用户名可以在导入后先ls /home看一眼有哪些用户目录通常就是你的用户名。4.6 第五步验证迁移结果别急着删 tar 和原发行版先做几项验证检查挂载和路径df -h看根分区大小是否正常pwd看家目录对不对。检查开发环境跑一下python --version、node -v、docker ps确认常用工具都在。检查 CUDA如果你装了 CUDA执行nvidia-smi和nvcc --version确认 GPU 还能用。检查文件权限ls -la看关键目录权限有没有乱特别是/home下的。跑一个实际项目编译一次、启动一次服务比任何检查都靠谱。全部正常后再执行wsl --unregister注销旧发行版删除 tar 文件释放空间。5. 迁移后常见问题与排查实录5.1 启动报错 The specified distribution name is invalid这个错误 90% 是发行版名写错了。wsl -l -v里的名字必须一字不差包括大小写和连字符。如果你导入时用了新名字那后续所有命令都要用新名字。另一个可能是导入时目录路径带了引号但引号没配对检查命令里的引号。5.2 迁移后磁盘空间没释放这是 WSL2 的经典问题。wsl --unregister之后vhdx 文件确实删了但如果你之前做过wsl --export又没删 tar空间自然没回来。还有一种情况是 Windows 的存储感知没及时更新重启一下资源管理器或等几分钟。如果发现新盘上的 vhdx 比预期大很多那是动态扩展的锅。在 WSL 里执行sudo fstrim -av然后关机再用diskpart压缩 vhdx需要先wsl --shutdowndiskpart select vdisk fileD:\WSL\Ubuntu-22.04\ext4.vhdx attach vdisk readonly compact vdisk detach vdisk exit这套组合拳能把虚高的 vhdx 压回实际使用量我实测过80G 的 vhdx 压完只剩 35G。5.3 Docker Desktop 迁移后连不上 WSLDocker Desktop 依赖docker-desktop和docker-desktop-data两个特殊发行版它们也有自己的 vhdx。如果你只迁移了 Ubuntu 没管这俩Docker 可能报 there was a problem with wsl。解决办法是在 Docker Desktop 设置里找到 Resources → WSL Integration重新勾选你的发行版或者干脆把 Docker Desktop 也重装一遍让它重新注册。更彻底的做法是把docker-desktop-data也一起迁移方法完全一样导出导入即可。但注意这个发行版不能直接wsl -d进去只能通过 Docker Desktop 管理。5.4 VS Code 远程连接失效在 VS Code 里用 WSL 的人迁移后可能发现 Remote-WSL 连不上。原因通常是 VS Code 缓存的 WSL 发行版信息过期了。解决CtrlShiftP打开命令面板执行Remote-WSL: Reopen in WSL或者干脆重启 VS Code。如果还不行删掉%USERPROFILE%\.vscode\extensions下的 WSL 相关扩展重装。5.5 常见问题速查表现象可能原因解决方向导入后是 root 用户未配置 wsl.conf编辑 /etc/wsl.conf 设 default启动卡在 Installingvhdx 路径权限问题检查目标目录 NTFS 权限CUDA 不可用驱动或路径变化重装 nvidia 驱动检查 /usr/local/cuda网络不通WSL 网络模式变化wsl --shutdown重启检查 DNS磁盘只读vhdx 被占用或损坏关机后 chkdsk 检查目标盘中文乱码编码设置丢失重设 locale 和 wsl 编码6. 几个能让你少走弯路的实操心得迁移这事我前后做过七八次从笔记本换 SSD 到给团队统一部署开发环境攒了些文档里不会写的经验。第一迁移前把 WSL 里的包管理器缓存清一遍。sudo apt clean、conda clean -a、pip cache purge能省下好几个 G 的导出体积。我见过一个 conda 环境缓存占了 15G 的清完导出快了一半。第二tar 文件别放 C 盘。很多人导出时顺手放桌面结果 C 盘更满了导入时又占一份直接爆盘。tar 直接放目标盘导入完再删。第三如果你要换硬盘顺序很重要。先把新硬盘装好、分区、格式化再执行导出导出到新盘然后导入到新盘最后注销旧的。别先拆旧盘不然 tar 都没地方放。第四团队协作场景下可以把配置好的 WSL 导出成 tar 当模板。新同事入职直接wsl --import一个预装好环境的 tar十分钟搞定开发环境比一个个装快多了。这个思路在做国产化迁移、统一开发环境时特别有用。第五迁移后记得更新/etc/wsl.conf里的[automount]配置。如果你原来配置了自动挂载 Windows 盘符迁移后这些配置还在但盘符路径可能变了检查一下ls /mnt确认。第六定期给 vhdx 做 compact。WSL2 用久了 vhdx 会虚胖我一般每季度 compact 一次能稳定回收 20% 到 40% 的空间。配合fstrim效果更好。最后分享一个判断迁移是否真的成功的土办法在 WSL 里touch一个新文件然后去 Windows 资源管理器里看目标目录的 vhdx 修改时间是不是刚刚更新了。如果是说明你的 WSL 确实跑在新路径上迁移实锤成功。这个验证比看命令输出直观多了尤其适合刚上手的人。