这篇文档是有时效的,最新记录时间是 2023/12 。
之后不会再更新,所以不包含 2024 的新状况。
背景
近期重新攒一台 PC,重做系统 Windows 11 并配置开发环境 WSL 2 + VSCode 。
本以为会比 Windows 10 配置 WSL 2 更简单,没想到居然遇到这么古怪的问题。
为了避免其他开发者浪费时间在这些奇葩问题,我把踩坑记录从个人语雀誊写一份,供各位参考。
记录
以下假设你已经在 Windows 11 的终端使用 PowerShell 以管理员身份执行 wsl --install
并成功。那么你应该已经可以在终端使用 WSL 2 默认搭配的 Ubuntu 。
以下问题截图不全,我懒得复现一遍截图了。
所以用文字描述。
问题一:WSL 2 不吃代理且反复提示 NAT
嗯,关键不是能不能代不代理,关键是每次启动终端都提醒 WSL 工作在 NAT 网络 ,很烦。
可以启用 WSL 2 的实验特性 镜像网络 解决这个问题。
在 Windows 的用户主目录 X:/Users/You 创建名为 .wslconfig
的 WSL 配置文件。
配置这些保存:
bash
[experimental]
autoMemoryReclaim=gradual # gradual | dropcache | disabled
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true
PowerShell 手动强制关掉 WSL 2,或者关掉终端等几分钟。
arduino
wsl --shutdown
重新打开终端即可。
感兴趣为什么可以参考这个官方文档 WSL 中的高级设置配置 | Microsoft Learn 。

问题二:code 命令启动 VSCode 提示 wsl.localhost 不是信任主机
老生常谈的 UNC 设置。

添加白名单,大概就可以了,其他选项我是顺手关了,懒得单因子验证了。
问题三:WSL 启动 VSCode 总是提醒不是 WSL 需要以推荐设置重启
假设你已经在 VSCode 安装 Remote 扩展。 参考官方这个说明 Visual Studio Code Remote Development 。

因为 Git 如果要正常使用必须要能工作在 WSL 模式,所以每次都不能自动 WSL 很麻烦。
这个问题在 Windows 10 的半吊子 WSL 2 上甚至都没遇到过,反而是跑到 Windows 11 浪费了好几个小时调查原因。
先说结论:
- 需要设置 Windows 11 隐私设置、

- 告知 VSCode 信任扩展目录。
手动在 Windows 打开 VSCode(不是从 WSL 启动),手动打开用户数据目录的 VSCode 扩展存储目录 X:/Users/You/.vscode 。VSCode 弹出信任目录提示,选择 信任 。
附:曲折的解决思路
因为太曲折了,还是要说一下解决过程,或许其他人遇到的问题和我不同,但是解决思路可以共享。
首先这个现象是不正常的。一般 code .
自动会以 WSL Remote 方式工作。
那就说明 VSCode 的 Code 启动命令脚本可能有问题,以前有过问题,所以我会有此怀疑。
于是,先看下 VSCode 的脚本实现 cat "$(where code)"
。
这个版本(1.85.1、20231228)的 Code 启动脚本长这样:
bash
#!/usr/bin/env sh
#
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
if [ "$VSCODE_WSL_DEBUG_INFO" = true ]; then
set -x
fi
COMMIT="0ee08df0cf4527e40edc9aa28f4b5bd38bbff2b2"
APP_NAME="code"
QUALITY="stable"
NAME="Code"
SERVERDATAFOLDER=".vscode-server"
VSCODE_PATH="$(dirname "$(dirname "$(realpath "$0")")")"
ELECTRON="$VSCODE_PATH/$NAME.exe"
IN_WSL=false
if [ -n "$WSL_DISTRO_NAME" ]; then
# $WSL_DISTRO_NAME is available since WSL builds 18362, also for WSL2
IN_WSL=true
else
WSL_BUILD=$(uname -r | sed -E 's/^[0-9.]+-([0-9]+)-Microsoft.*|.*/\1/')
if [ -n "$WSL_BUILD" ]; then
if [ "$WSL_BUILD" -ge 17063 ]; then
# WSLPATH is available since WSL build 17046
# WSLENV is available since WSL build 17063
IN_WSL=true
else
# If running under older WSL, don't pass cli.js to Electron as
# environment vars cannot be transferred from WSL to Windows
# See: https://github.com/microsoft/BashOnWindows/issues/1363
# https://github.com/microsoft/BashOnWindows/issues/1494
"$ELECTRON" "$@"
exit $?
fi
fi
fi
if [ $IN_WSL = true ]; then
export WSLENV="ELECTRON_RUN_AS_NODE/w:$WSLENV"
CLI=$(wslpath -m "$VSCODE_PATH/resources/app/out/cli.js")
# use the Remote WSL extension if installed
WSL_EXT_ID="ms-vscode-remote.remote-wsl"
ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" --ms-enable-electron-run-as-node --locate-extension $WSL_EXT_ID >/tmp/remote-wsl-loc.txt 2>/dev/null </dev/null
WSL_EXT_WLOC=$(cat /tmp/remote-wsl-loc.txt)
if [ -n "$WSL_EXT_WLOC" ]; then
# replace \r\n with \n in WSL_EXT_WLOC
WSL_CODE=$(wslpath -u "${WSL_EXT_WLOC%%[[:cntrl:]]}")/scripts/wslCode.sh
"$WSL_CODE" "$COMMIT" "$QUALITY" "$ELECTRON" "$APP_NAME" "$SERVERDATAFOLDER" "$@"
exit $?
fi
elif [ -x "$(command -v cygpath)" ]; then
CLI=$(cygpath -m "$VSCODE_PATH/resources/app/out/cli.js")
else
CLI="$VSCODE_PATH/resources/app/out/cli.js"
fi
ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" --ms-enable-electron-run-as-node "$@"
exit $?
第 43 行到第 55 行就是识别到 WSL 应该执行的启动脚本。实际简单调试就会发现没有走到。 其中,第 46 行是通过 Node 工作模式调用 Code.exe 执行 cli.js 反查 ms-vscode-remote.remote-wsl 插件的位置。查找结果是 WSL 扩展的目录路径,会标准输出到一个临时文件。
后续逻辑如果这个临时文件内容为空,表示查找不到插件,就会走到未识别 WSL 的路径。 上面那个弹窗反复出现,就是因为未识别到 WSL 的路径。
知道问题原因,就可以尝试解决问题了。
尝试单独执行第 46 行,会遇到两种错误,一个是显式的执行报错。没有截图。 从报错大概可以看到 LastRecents,一番搜索发现居然是因为关掉了 最近打开的文件 这个隐私开关。 打开后再次执行,这个报错没有了,但是依然不能输出正确的扩展目录。
一番苦思冥想,从这个奇葩的隐私报错,突然联想到会不会是 VSCode 没有访问扩展目录的权限导致。 于是,直接从 Windows 打开 VSCode,打开用户主目录的 VSCode 扩展存储目录 X:/Users/You/.vscode 。 果然看到 VSCode 弹出信任目录提示,选择 信任 。
再次执行 code .
,即带上环境变量执行上面的脚本,发现临时文件写入目录了,VSCode 已经可以自动识别 WSL 环境并连接。