WSL + VSCode 开发 .NET 项目:把 NuGet 源改到 TaoToken 的完整配置

发布时间:2026/10/18 11:09:02
WSL + VSCode 开发 .NET 项目:把 NuGet 源改到 TaoToken 的完整配置
1. WSL 里 dotnet restore 卡住或 401问题到底出在哪在 Windows 上用 WSL VSCode 写 .NET 项目最容易被忽略的一步不是写代码而是包还原。你敲下dotnet restore终端可能停在Determining projects to restore...十几分钟不动也可能几秒后甩出一行error: Unable to load the service index for source https://api.nuget.org/v3/index.json再配一个401 Unauthorized或response status code does not indicate success。这不是你的代码写错了而是 NuGet 在跟默认源通信时出了问题。NuGet 源是什么你可以把它理解成 .NET 世界的应用商店。dotnet add package Newtonsoft.Json这条命令背后就是 NuGet 客户端去某个源地址拉取包元数据和.nupkg文件。默认情况下这个源是https://api.nuget.org/v3/index.json。问题在于WSL 的网络栈和 Windows 主机是两套东西DNS 解析、TLS 握手、代理继承都可能不一致。Windows 浏览器能打开的地址WSL 里的curl未必通反过来也一样。401 这个状态码尤其值得说。它表示“未授权”通常意味着请求到达了服务端但缺少有效的身份凭证。在 NuGet 场景里401 常见于三种情况一是源地址本身要求鉴权而你的NuGet.config里没有配 Key二是配了 Key 但环境变量没被 WSL 读到三是 Key 写在了 Windows 侧的配置文件里WSL 用的是 Linux 家目录下的另一份配置两边根本没对上。很多人改了%AppData%\NuGet\NuGet.Config就以为万事大吉结果 WSL 里dotnet restore读的是~/.nuget/NuGet/NuGet.Config自然还是 401。还原慢则是另一条线。默认源在境外WSL 的 DNS 又经常继承 Windows 的解析结果导致请求绕路。表现就是dotnet restore每个包都要等很久dotnet build跟着一起慢。这时候把源换成一个响应更稳定的地址是最直接的解法。TaoToken 提供统一的 API 入口把 NuGet 源指向它配合一个统一 Key就能让 WSL 里的还原走同一条可控通道。适合谁看这篇如果你正在 Windows 上用 WSL2 跑 Ubuntu用 VSCode 的 WSL 远程插件开发 .NET 6/8/9 项目并且被dotnet restore的慢或 401 卡过那这篇就是给你写的。下面我会从环境确认开始一步步给出可复制的NuGet.config、Key 的写入位置、验证命令以及报错排查对照表。全程在 WSL 终端里操作不需要你切换回 Windows 命令行。先说清楚一个前提TaoToken 在这里扮演的是“统一的包源入口 统一 Key 管理”的角色不是让你绕过什么。你依然是在正常地做包还原只是把源地址和凭证集中到一处方便 WSL 和 Windows 两边保持一致。理解这一点后面的配置就不会觉得别扭。2. 前置准备WSL 里的 .NET SDK、VSCode 远程与 TaoToken Key动手改源之前先把地基确认一遍。很多 401 其实是 SDK 没装对或者 VSCode 没连上 WSL 导致的假象。我按顺序给你捋。第一步确认 WSL 发行版和 .NET SDK。打开 WSL 终端在 VSCode 里按Ctrl也行执行dotnet --list-sdks正常输出类似8.0.404 [/usr/share/dotnet/sdk] 9.0.101 [/usr/share/dotnet/sdk]如果提示command not found说明 SDK 没装。Ubuntu 24.04 下可以这样装注意用官方 backports 源别混用sudo add-apt-repository ppa:dotnet/backports sudo apt update sudo apt install -y dotnet-sdk-8.0 sudo apt install -y dotnet-sdk-9.0装完再跑一次dotnet --list-sdks确认。这里有个坑如果你同时装了dotnet-sdk-6.0和 8/9dotnet默认会用最高版本项目TargetFramework写net8.0时要注意 SDK 是否匹配。用dotnet --version看当前生效版本。第二步VSCode 连接 WSL。在 Windows 的 VSCode 里装 “WSL” 扩展然后左下角绿色按钮选择 “Connect to WSL”。连上后VSCode 的终端就是 WSL 的 shell文件路径也是 Linux 路径。这一步没连上你在 VSCode 里改的NuGet.config可能落在 Windows 侧WSL 根本读不到。第三步准备 TaoToken 的 Key。访问控制台创建 API Keyhttps://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentnuget_wsl_vscodeutm_campaignrewrite创建后你会拿到一串以sk-开头的 Key。先别急着写进文件我们后面会用环境变量 配置文件两种方式处理。顺手把接入文档也打开对照https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentnuget_wsl_vscodeutm_campaignrewrite第四步确认 WSL 能访问外网。执行curl -I https://taotoken.net/api如果返回HTTP/2 200或401取决于是否带 Key说明网络通。如果卡住或Could not resolve host先解决 WSL 的 DNS别急着改 NuGet。DNS 问题可以临时在/etc/resolv.conf里加nameserver 8.8.8.8验证但注意 WSL 重启会覆盖长期方案是改/etc/wsl.conf。第五步确认项目目录权限。如果你在/home/你的用户名/codestudy/dotnetstu下建项目确保目录属于当前用户whoami groups sudo chown -R $USER:$USER /home/$USER/codestudy/dotnetstu权限不对会导致dotnet restore写obj/失败报错看起来像源的问题其实是磁盘写不进去。这一步别省。做完这五步你手里应该有可用的dotnet、连上 WSL 的 VSCode、一个 TaoToken Key、能通的网络、可写的项目目录。接下来才是改源。3. 可复制配置NuGet.config 片段与 TaoToken Key 写入位置这一节是核心给你能直接抄的配置。先明确一个原则WSL 里的 NuGet 配置优先级是“项目目录 用户目录 机器级”。我们主要动用户级配置~/.nuget/NuGet/NuGet.Config再在项目里放一份覆盖保证团队协作时一致。先看用户级配置。在 WSL 终端执行mkdir -p ~/.nuget/NuGet nano ~/.nuget/NuGet/NuGet.Config写入以下内容把你的Key换成实际 Key?xml version1.0 encodingutf-8? configuration packageSources clear / add keytaotoken valuehttps://taotoken.net/api/nuget/v3/index.json / /packageSources packageSourceCredentials taotoken add keyUsername valuetaotoken / add keyClearTextPassword value你的Key / /taotoken /packageSourceCredentials /configuration注意clear /这行它会清掉继承来的默认源避免nuget.org还在列表里拖慢还原。packageSourceCredentials里的Username随便填NuGet 只认ClearTextPassword。Key 直接写明文在配置文件里适合个人开发机如果是共享机器改用环境变量见下面。项目级配置放在项目根目录文件名NuGet.config注意大小写Linux 区分?xml version1.0 encodingutf-8? configuration packageSources clear / add keytaotoken valuehttps://taotoken.net/api/nuget/v3/index.json / /packageSources /configuration项目级不写 KeyKey 从用户级或环境变量继承。这样提交到 Git 时不会泄露凭证。如果你不想把 Key 写进文件用环境变量。在~/.bashrc或~/.zshrc末尾加export TAOTOKEN_NUGET_KEY你的Key然后source ~/.bashrc。但 NuGet 原生不读这个变量需要配合nuget.config里的%TAOTOKEN_NUGET_KEY%语法——注意 NuGet 在 Linux 下对%VAR%的支持有限更稳的做法是用dotnet nuget add source命令带--password参数它会帮你写进加密存储dotnet nuget remove source taotoken 2/dev/null dotnet nuget add source https://taotoken.net/api/nuget/v3/index.json \ --name taotoken \ --username taotoken \ --password $TAOTOKEN_NUGET_KEY \ --store-password-in-clear-text--store-password-in-clear-text在 Linux 下是必要的因为默认的加密存储依赖 Windows DPAPIWSL 里用不了。这条命令执行后~/.nuget/NuGet/NuGet.Config会自动更新你可以cat出来核对。再给一个 VSCode 侧的配置片段。如果你用 C# Dev Kit 或 OmniSharp它们会读工作区的.vscode/settings.json。加一行指定 SDK 路径避免找不到{ dotnet.server.useOmnisharp: false, omnisharp.dotNetCliPaths: [ /usr/share/dotnet/dotnet ], dotnet.defaultSolution: MyConsoleApp.sln }这里没有直接配 NuGet 源因为源是dotnetCLI 层的事VSCode 插件只是调用 CLI。但把 SDK 路径写对能避免插件报“找不到 dotnet”而让你误以为是源的问题。最后强调 Key 的写入位置优先级项目NuGet.config里的packageSourceCredentials 用户级NuGet.Configdotnet nuget add source写入的加密存储。实际排查时用dotnet nuget list source看当前生效的源列表用dotnet nuget locals all --list看缓存位置。缓存目录~/.nuget/packages如果残留了旧的失败记录可以dotnet nuget locals all --clear清掉再还原。4. 验证请求dotnet restore 成功输出与调试配置配置写完必须验证。别直接开写业务代码先用一个最小项目跑通还原。创建项目mkdir -p ~/codestudy/dotnetstu cd ~/codestudy/dotnetstu dotnet new console -o MyConsoleApp cd MyConsoleApp此时目录里应该有MyConsoleApp.csproj、Program.cs。先看源列表dotnet nuget list source预期输出Registered Sources: 1. taotoken [Enabled] https://taotoken.net/api/nuget/v3/index.json如果还看到nuget.org说明clear /没生效检查配置文件路径和 XML 格式。然后执行还原dotnet restore --verbosity normal成功时你会看到类似Determining projects to restore... Restored /home/wjl/codestudy/dotnetstu/MyConsoleApp/MyConsoleApp.csproj (in 1.2 sec).注意in 1.2 sec这个时间如果换成默认源同样的项目可能要 10 秒以上。--verbosity normal会打印实际请求的源地址你能看到GET https://taotoken.net/api/nuget/v3/index.json这样的行确认走的是新源。加一个包再还原验证凭证生效dotnet add package Newtonsoft.Json --version 13.0.3 dotnet restore如果 Key 不对这一步会报 401。正确配置下输出里会有PackageReference for package Newtonsoft.Json version 13.0.3 added还原无报错。接着配调试。在.vscode/launch.json写入{ version: 0.2.0, configurations: [ { name: debugTest01, type: coreclr, request: launch, preLaunchTask: build, program: ${workspaceFolder}/MyConsoleApp/bin/Debug/net9.0/MyConsoleApp.dll, cwd: ${workspaceFolder}, requireExactSource: false, env: { ASPNETCORE_ENVIRONMENT: Development } } ] }同目录.vscode/tasks.json{ version: 2.0.0, tasks: [ { label: build, command: dotnet, type: process, args: [ build, ${workspaceFolder} ], problemMatcher: $msCompile } ] }注意program里的路径要和你的TargetFramework一致。项目是net9.0就写net9.0是net8.0就改掉。preLaunchTask指向tasks.json里的build这样按 F5 时会先构建再调试。改一下Program.csusing Newtonsoft.Json; var obj new { Name TaoToken, Type NuGet }; var json JsonConvert.SerializeObject(obj); Console.WriteLine(json);按 F5终端输出{Name:TaoToken,Type:NuGet}能断点、能输出说明还原、构建、调试整条链路通了。如果 F5 报The preLaunchTask build terminated with exit code 1先看dotnet build的报错多半还是还原没成功。5. 常见报错排查401、local proxy failed、reading choices 对照这一节按真实报错来。你在 WSL 里大概率会遇到下面几种我给出原因和修法。报错一401 Unauthorized或response status code does not indicate success: 401原因通常是 Key 没被读到。先确认源列表和凭证dotnet nuget list source cat ~/.nuget/NuGet/NuGet.Config看packageSourceCredentials里的ClearTextPassword是不是你的 Key。如果用了dotnet nuget add source检查是否带了--store-password-in-clear-text。没带的话Linux 下凭证存不进去还原时就是 401。修法删掉源重新加dotnet nuget remove source taotoken dotnet nuget add source https://taotoken.net/api/nuget/v3/index.json \ --name taotoken --username taotoken \ --password 你的Key --store-password-in-clear-text还有一种 401 是 Key 过期或被禁用去控制台重新生成一个https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentnuget_wsl_vscodeutm_campaignrewrite报错二local proxy failed或Unable to connect to the remote serverWSL 的网络和 Windows 主机是隔离的。如果你在 Windows 上设了系统代理WSL 默认不继承。表现就是curl能通但dotnet restore报连接失败。检查env | grep -i proxy如果输出里有http_proxy指向127.0.0.1:某端口而 WSL 里那个端口没有服务就会失败。修法清掉这些变量或者把代理地址改成 WSL 能访问的 Windows 主机 IPcat /etc/resolv.conf里的nameserver通常是主机 IP。但更简单的做法是让 NuGet 直连不经过代理unset http_proxy https_proxy all_proxy dotnet restore如果必须走代理在NuGet.config里加config add keyhttp_proxy valuehttp://主机IP:端口 / /config报错三Error reading choices或Unable to load the service index这个多半是源地址写错了。NuGet v3 源的地址必须以index.json结尾。检查你的NuGet.configadd keytaotoken valuehttps://taotoken.net/api/nuget/v3/index.json /少写/v3/index.json或者写成/api/nuget都会导致读取失败。用curl直接验证curl -s https://taotoken.net/api/nuget/v3/index.json | head -c 200正常会返回一段 JSON包含version和resources字段。如果返回 HTML 或 404说明地址不对。报错四OAuth相关或The plugin credential provider could not acquire credentials这是 NuGet 的凭证插件在 Linux 下找不到合适的提供程序。WSL 里没有 Windows 的凭据管理器插件会失败。修法就是前面说的用--store-password-in-clear-text或者直接在NuGet.config里写ClearTextPassword。别用dotnet nuget add source不带这个参数否则凭证存不进去还原时插件报 OAuth 错误。报错五NU1101 Unable to find package源换了但包找不到。先确认包名拼写再确认源里确实有这个包。用dotnet package search Newtonsoft.Json --source taotoken如果搜不到可能是源地址不对或 Key 无权限。对照dotnet nuget list source的输出确认taotoken是 Enabled 状态。排查顺序建议固定成先dotnet nuget list source看源再curl看网络再cat看配置最后dotnet restore --verbosity normal看详细日志。90% 的问题在前三步就能定位。6. 把源固定下来长期开发与 Coding Plan 的配合配置改完不是终点。WSL 有个特性重启后/etc/resolv.conf可能被覆盖网络环境变化会让之前的源地址解析出问题。所以长期开发要做的是把配置固化并且让团队里每个人拿到项目就能还原。第一件事把项目级NuGet.config提交到 Git。这样新同事 clone 下来dotnet restore自动走 TaoToken 源不需要手动配。项目级配置里不写 KeyKey 由每个人的用户级配置或环境变量提供。在README.md里写清楚 Key 的获取地址https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentnuget_wsl_vscodeutm_campaignrewrite第二件事处理 WSL 的 DNS 持久化。编辑/etc/wsl.conf[network] generateResolvConf false然后在/etc/resolv.conf里写固定的nameserver。改完在 Windows 侧执行wsl --shutdown重启 WSL 生效。这一步能避免每次重启后 DNS 变化导致的还原失败。第三件事清理缓存。换源后旧的缓存可能还在~/.nuget/packages偶尔会导致“明明换了源还用旧包”的错觉。定期执行dotnet nuget locals all --clear dotnet restore第四件事如果你同时用 Claude Code 或 Codex 这类编码工具它们的配置也可以统一到 TaoToken。Claude Code 的接入文档在这里https://taotoken.net/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contentnuget_wsl_vscodeutm_campaignrewriteCodex 的auth.json里 Base URL 填https://taotoken.net/apiKey 用同一个Model ID 按文档填。这样 NuGet 源、编码工具、模型对话三处的凭证是同一套管理成本最低。如果你长期在 WSL 里做 .NET 开发配合 Coding Plan 会更省心https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentnuget_wsl_vscodeutm_campaignrewrite最后给一个日常检查清单贴在终端旁边dotnet --list-sdks dotnet nuget list source curl -s -o /dev/null -w %{http_code} https://taotoken.net/api/nuget/v3/index.json dotnet restore --verbosity minimal四条命令跑一遍全绿就可以安心写代码。哪条红了回到第 5 节对照报错。这套流程我在多个 WSL 环境里跑过最常出问题的还是 Key 没写对和 DNS 没固定把这两点处理好dotnet restore基本不会再卡你。