摘要
VS Code 离线迁移,最容易漏的不是插件目录,而是 WSL 里的那套东西。
很多人迁移时只拷了 Windows 里的这个目录:
%USERPROFILE%\.vscode\extensions
拷完一看,本地主题、图标、快捷键都在,好像已经恢复了。可是一打开 WSL 项目,VS Code 又开始下载 Server;或者窗口能打开,但 Python、C++、Rust 这些扩展在 WSL 里还是不可用。
这时候问题通常不在插件包本身,而在迁移对象没分清。
VS Code + WSL 至少有三块要处理:
- Windows 上的 VS Code 主程序;
- Windows 上的本地插件和用户配置;
- WSL 里的 VS Code Server 和远程插件。
本文记录一套比较稳的离线迁移方式。它不追求做成万能同步工具,只解决一个具体问题:在不能联网的机器上,把一套已经能用的 VS Code + Remote WSL 环境恢复起来。
一、分清哪些东西在 Windows,哪些东西在 WSL
不要一上来就打包插件。先把位置弄清楚。
VS Code 官方文档里有一个关键点:使用 WSL 扩展时,VS Code 会把命令和大多数扩展放到 WSL 里运行,并在 WSL 内安装 VS Code Server。这个 Server 和你在 WSL 里有没有单独安装 VS Code 不是一回事。
现场看,大概是这样:
Windows
├─ VS Code 主程序
├─ 本地插件:%USERPROFILE%\.vscode\extensions
└─ 用户配置:%APPDATA%\Code\User
WSL
└─ ~/.vscode-server
├─ VS Code Server
├─ 远程插件
└─ 远程侧配置和缓存
本地插件一般管 UI、主题、图标、快捷键,以及一部分客户端能力。
远程插件才是在 Linux 文件系统、Linux 工具链和语言服务旁边运行的那部分。
比如 Python、C/C++、Go、Rust、Docker、CMake 这些扩展,在 WSL 项目里通常要装到 WSL 侧。你只恢复 Windows 插件目录,它们在远程窗口里还是可能缺。
二、在能联网的机器上打包
离线迁移不要到离线机器上才开始补东西。
更稳的做法是先找一台已经跑通 VS Code + WSL 的联网机器,在那台机器上把包准备好。因为到了离线机器上,真正麻烦的往往不是 VS Code 安装包,而是 Server 版本、扩展版本和远程目录结构对不上。
下面假设迁移包放在:
D:\vscode-offline
先建目录:
New-Item -ItemType Directory -Force D:\vscode-offline
New-Item -ItemType Directory -Force D:\vscode-offline\vsix
1. 记录 VS Code 版本和 commit
VS Code Server 跟桌面端版本绑定得很紧。先把版本记下来:
code --version > D:\vscode-offline\vscode-version.txt
这个文件一般有三行:版本号、commit id、架构。后面最该盯的是第二行 commit id。
离线机器上的 VS Code 如果和原机器不是同一个 commit,它很可能会去找另一份 VS Code Server。能联网时这只是等一会儿,不能联网时就会卡住。
2. 导出本地插件列表
先留一份清单,方便后面核对:
code --list-extensions --show-versions > D:\vscode-offline\vscode-local-extensions.txt
然后打包本地插件目录:
Compress-Archive `
-Path "$env:USERPROFILE\.vscode\extensions" `
-DestinationPath D:\vscode-offline\vscode-local-extensions.zip `
-Force
如果你已经这样打包了本地扩展目录,后面恢复时就直接解压,不需要再给这些本地扩展逐个准备 VSIX。
VSIX 也不是不能用。它更适合两种情况:
- 你没有打包本地扩展目录,只想带几个固定扩展;
- 你要单独准备 Windows 侧的 Remote WSL 入口扩展。
如果确实要走 VSIX,在扩展市场里右键选择 Download VSIX 或 Download Specific Version VSIX,放到:
D:\vscode-offline\vsix
3. 备份 VS Code 用户配置
插件只是插件,配置也要带走。
至少把用户配置目录打包:
Compress-Archive `
-Path "$env:APPDATA\Code\User" `
-DestinationPath D:\vscode-offline\vscode-user.zip `
-Force
这里面通常有:
settings.jsonkeybindings.json- snippets
- tasks
- 一些用户状态数据
如果你用了 Profile,别只盯默认 User 目录。Profile 相关配置可能在单独目录里,需要按实际情况一起带走。
三、把 WSL 里的 VS Code Server 一起打包
这一块最容易被忽略。
如果你的目标只是恢复 Windows 本地 VS Code,前面那些基本够了。可如果你要在离线机器上继续打开 WSL 项目,就要把 WSL 里的 .vscode-server 也带走。
先看发行版名称:
wsl -l -v
假设发行版叫 Ubuntu-22.04,在 PowerShell 里执行:
wsl -d Ubuntu-22.04 -- bash -lc "tar -czf /mnt/d/vscode-offline/wsl-vscode-server.tgz -C ~ .vscode-server"
这会把 WSL 用户目录下的 .vscode-server 打包到 Windows 的 D:\vscode-offline。
想留一份远程插件清单的话,再跑:
wsl -d Ubuntu-22.04 -- bash -lc "find ~/.vscode-server/extensions -maxdepth 1 -mindepth 1 -printf '%f\n' | sort > /mnt/d/vscode-offline/vscode-wsl-extensions.txt"
这里别只备份:
~/.vscode-server/extensions
只带远程插件目录,可能会漏掉 Server 本体。离线机器第一次连 WSL 时,VS Code 还是可能提示安装或下载 Server。
更省心的做法是整包带走:
~/.vscode-server
如果你用的是 Insiders,对应目录通常是:
~/.vscode-server-insiders
四、准备 VS Code 安装包和 Remote WSL 扩展
离线机器上要先装 VS Code 主程序,版本最好和原机器一致。
另外,Windows 侧还要有 Remote WSL 入口扩展。它的扩展 ID 是:
ms-vscode-remote.remote-wsl
在联网机器上打开这个扩展页,右键下载 VSIX,放到:
D:\vscode-offline\vsix
如果你平时装的是 Remote Development 扩展包,也可以一起带上。但真正连接 WSL 必须有的是 Remote WSL 扩展。
整理完以后,迁移包大概是这样:
D:\vscode-offline
├─ VS Code 安装包
├─ vscode-version.txt
├─ vscode-local-extensions.txt
├─ vscode-local-extensions.zip
├─ vscode-user.zip
├─ wsl-vscode-server.tgz
├─ vscode-wsl-extensions.txt
└─ vsix
├─ ms-vscode-remote.remote-wsl-*.vsix
└─ 其他需要离线安装的扩展
其中 vsix 目录不是用来重复安装所有本地插件的。已经打包进 vscode-local-extensions.zip 的本地插件,后面直接解压就行。
五、在离线机器上恢复 Windows 侧
先安装 VS Code。版本尽量和 vscode-version.txt 里记录的一致。
装完后看一眼:
code --version
如果 commit id 不一样,先别急着打开 WSL 项目。版本不一致时,后面最容易卡在 Server 下载。
1. 恢复本地插件目录
如果你已经打包了:
%USERPROFILE%\.vscode\extensions
那本地普通扩展不需要再安装 VSIX。直接解压:
Expand-Archive `
-Path D:\vscode-offline\vscode-local-extensions.zip `
-DestinationPath "$env:USERPROFILE\.vscode" `
-Force
这里要看你压缩包里的层级。
如果压缩包里已经包含 extensions 目录,解压目标就是:
%USERPROFILE%\.vscode
如果你压缩时只压了 extensions 目录里面的子项,解压目标就要改成:
%USERPROFILE%\.vscode\extensions
不要恢复完本地扩展目录后,又把同一批插件用 VSIX 装一遍。没有必要,还容易把版本搞乱。
VSIX 留给 Remote WSL 入口扩展,或者你没有打包目录时再用:
Get-ChildItem D:\vscode-offline\vsix\*.vsix | ForEach-Object {
code --install-extension $_.FullName --force
}
如果 vsix 目录里只放了 ms-vscode-remote.remote-wsl,那这条命令就是安装 Remote WSL 扩展。
2. 恢复用户配置
再恢复用户配置:
Expand-Archive `
-Path D:\vscode-offline\vscode-user.zip `
-DestinationPath "$env:APPDATA\Code" `
-Force
做完这一步,打开 VS Code,本地主题、快捷键、设置大概率已经回来了。
但这还不能说明 WSL 项目能用。远程侧还没恢复。
六、在离线机器上恢复 WSL 侧
先确认离线机器上的 WSL 发行版能启动:
wsl -l -v
wsl -d Ubuntu-22.04
发行版名称可以和原机器不一样。只要后面的命令用实际名称就行。
回到 Windows PowerShell,解压 .vscode-server:
wsl -d Ubuntu-22.04 -- bash -lc "tar -xzf /mnt/d/vscode-offline/wsl-vscode-server.tgz -C ~"
然后检查:
wsl -d Ubuntu-22.04 -- bash -lc "ls -la ~/.vscode-server"
能看到 extensions、data、bin 或 cli 这些目录,基本就说明恢复进去了。
这里多说一句。不同 VS Code 版本里的 Server 目录结构会变。旧资料经常写:
~/.vscode-server/bin/<commit>
新版本里也可能是:
~/.vscode-server/cli/servers/Stable-<commit>/server
所以如果你手里有原机器,优先迁移整份 .vscode-server,不要手工猜目录。只要桌面 VS Code 版本一致,这条路省事很多。
七、打开 WSL 项目先做小验证
恢复完先别直接开大项目。
用最小路径测一下:
code --remote wsl+Ubuntu-22.04 /home
或者进 WSL 终端执行:
code .
正常情况是:VS Code 打开 WSL 窗口,左下角显示 WSL: Ubuntu-22.04,不会长时间停在下载 VS Code Server。
再打开扩展面板,看分组:
Local - Installed:Windows 本地插件;WSL: Ubuntu-22.04 - Installed:WSL 侧远程插件。
如果 Python、C/C++、Go、Rust 这些扩展出现在 WSL 分组里,说明远程插件位置对了。
还可以从命令面板执行:
Developer: Show Running Extensions
这个命令能看到扩展到底跑在本地,还是跑在远程扩展宿主里。排查扩展位置时很有用。
八、常见问题
1. 还是提示下载 VS Code Server
先看版本,不要先删目录。
在离线机器上执行:
code --version
把第二行 commit id 和原机器的 vscode-version.txt 对一下。只要不一致,当前 VS Code 就可能在找另一份 Server。
处理办法通常就两个:
- 把离线机器 VS Code 换成和原机器一致的版本;
- 回到联网机器,按离线机器这个版本重新准备
.vscode-server。
不要反复删除 .vscode-server。删完以后,VS Code 更没东西可用,只会继续下载。
2. 本地插件恢复了,WSL 里还是没有
这不是同一个位置。
VS Code 扩展会运行在本地 UI 侧,也会运行在 WSL 侧。主题、图标这类通常在本地,语言服务、调试器这类通常要进 WSL。
先检查远程目录:
wsl -d Ubuntu-22.04 -- bash -lc "ls ~/.vscode-server/extensions"
如果目录为空,说明远程插件没恢复进去。回到第三节,从原机器重新打包 .vscode-server。
3. 扩展在,但语言服务不可用
这时候别只盯 VS Code。
远程扩展跑在 WSL 里,它依赖的也是 WSL 里的工具链。比如:
- Python 扩展需要 WSL 里有 Python 环境;
- C/C++ 扩展需要编译器、头文件和调试器;
- Rust 扩展需要
rustup、cargo或语言服务; - Docker 扩展要看 Docker Desktop 或 Linux 侧 Docker 是否可用。
插件恢复只能恢复编辑器侧能力,不能替你恢复系统依赖。
4. 换了 WSL 用户后插件找不到
.vscode-server 在当前用户的家目录下。
原来可能是:
/home/olduser/.vscode-server
离线机器上可能变成:
/home/newuser/.vscode-server
压缩包要解到新用户的家目录下,权限也要属于当前用户:
wsl -d Ubuntu-22.04 -- bash -lc 'sudo chown -R "$(id -un):$(id -gn)" ~/.vscode-server'
如果你是用 root 解压的,这一步一定要看。
5. 能不能只下载 VS Code Server
可以,但我不把它放在首选。
有些教程会让你根据 commit id 下载 server-linux-x64 压缩包,再手工解压到指定目录。这个办法能解决一些 Remote SSH 或 WSL 离线安装问题,但目录结构会受 VS Code 版本影响。
如果你手里有一台已经跑通的原机器,直接迁移整份 .vscode-server 更少折腾。
只有在原机器已经拿不到、必须从零准备离线包时,再考虑按 commit id 下载对应 Server,并按当前版本的目录结构放好。
九、检查清单
迁移完,我一般按下面顺序看:
code --version和原机器一致。- Windows 本地扩展列表能对上
vscode-local-extensions.txt。 %APPDATA%\Code\User\settings.json已恢复。- WSL 里存在
~/.vscode-server。 - WSL 里存在
~/.vscode-server/extensions。 code --remote wsl+发行版名 /home能打开窗口。- 扩展面板里能看到
WSL: 发行版名 - Installed分组。 - 打开项目后,语言服务、终端、调试器都在 WSL 环境里工作。
这些都没问题,基本就能认为迁移成功了。
小结
VS Code 离线迁移,别只拷本地插件目录。
真正要带走的是三块:
- Windows 本地 VS Code、本地插件和用户配置;
- Windows 侧 Remote WSL 入口扩展;
- WSL 里的 VS Code Server 和远程插件。
最容易漏的还是 ~/.vscode-server。它里面有 Server,也有远程扩展和远程侧数据。只要 VS Code 版本一致,把这部分完整迁过去,比现场临时补包靠谱得多。
如果你要处理的是内网机、涉密机、生产机或临时交付环境,建议提前在联网机器上把安装包、配置、插件目录、Remote WSL VSIX 和 WSL Server 一起打好包。现场最怕的不是命令多,而是离线以后才发现少了一块。
评论区