配置 C# 调试
您可以使用 launch.json
、launchSettings.json
或用户 settings.json
文件在 Visual Studio Code 中配置 C# 调试器。
演练:设置命令行参数
在深入了解所有可能的选项之前,让我们先来看一个基本场景:为程序设置命令行参数。这些步骤也适用于更新其他基本选项,如环境变量或当前工作目录。
方法 1:launchSettings.json
对于 C# Dev Kit,推荐的调试方式是让 C# Dev Kit 根据项目文件中的设置自动确定如何调试。这意味着您要么没有 <workspace_root>/.vscode/launch.json
文件,要么如果有,则活动配置中设置了 "type": "dotnet"
。对于命令行参数,"根据项目文件确定" 意味着从 <Project-Directory>/Propeties/launchSettings.json
中提取值。launchSettings.json
的优势在于它允许在 Visual Studio Code、完整的 Visual Studio 和 dotnet run
之间共享设置。
在这种情况下,以下是设置命令行参数的步骤
- 在工作区资源管理器视图中,导航到要启动的项目目录(.csproj 文件)
- 如果尚不存在
Properties
目录,请创建它 - 如果尚不存在
launchSettings.json
文件,请创建一个,您可以使用以下文本作为示例 - 将
commandLineArgs
属性更改为您希望的命令行参数值
launchSettings.json
文件示例:
{
"profiles": {
"MyLaunchProfileName": {
"commandName": "Project",
"commandLineArgs": "MyFirstArgument MySecondArgument"
}
}
}
方法 2:launch.json
如果您在 VS Code 中使用 coreclr
或 clr
调试适配器类型,命令行参数存储在 <workspace_root>/.vscode/launch.json
文件中。在这种情况下,要编辑它们
- 打开
<workspace_root>/.vscode/launch.json
文件 - 找到您要启动的
coreclr
或clr
启动配置 - 编辑
args
属性。它可以是一个字符串,或一个字符串数组
配置 launchSettings.json
借助 C# Dev Kit,您可以将 Visual Studio 中的 launchSettings.json
文件用于 Visual Studio Code
示例
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:59481",
"sslPort": 44308
}
},
"profiles": {
"EnvironmentsSample": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7152;http://localhost:5105",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"EnvironmentsSample-Staging": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7152;http://localhost:5105",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Staging",
"ASPNETCORE_DETAILEDERRORS": "1",
"ASPNETCORE_SHUTDOWNTIMEOUTSECONDS": "3"
}
},
"EnvironmentsSample-Production": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7152;http://localhost:5105",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
配置文件属性
commandLineArgs
- 要传递给正在运行的目标的参数。executablePath
- 可执行文件的绝对或相对路径。workingDirectory
- 设置命令的工作目录。launchBrowser
- 如果应启动浏览器,则设置为true
。applicationUrl
- 要为 Web 服务器配置的 URL(或多个 URL)的半角分号分隔列表。sslPort
- 用于网站的 SSL 端口。httpPort
- 用于网站的 HTTP 端口。
可配置选项列表
以下是调试时可能需要更改的常见选项。
PreLaunchTask
preLaunchTask
字段在调试程序之前运行 tasks.json
中关联的 taskName。您可以通过从 VS Code 命令面板执行命令 Tasks: Configure Tasks Runner 来获取默认的构建 prelaunch 任务。
这将创建一个运行 dotnet build
的任务。您可以在 VS Code 任务 文档中了解更多信息。
可用性
launch.json
✔️settings.json
❌launchSettings.json
❌
Program
program 字段设置为要启动的应用程序 dll 或 .NET Core 主机可执行文件的路径。
此属性通常采用以下形式:"${workspaceFolder}/bin/Debug/<target-framework>/<project-name.dll>"。
示例:"${workspaceFolder}/bin/Debug/netcoreapp1.1/MyProject.dll"
其中
- <target-framework> 是调试项目构建时所针对的框架。这通常在项目文件中作为 'TargetFramework' 属性找到。
- <project-name.dll> 是调试项目构建输出 dll 的名称。这通常与项目文件名相同,但带有 '.dll' 扩展名。
可用性
launch.json
✔️settings.json
❌launchSettings.json
✔️ 作为executablePath
Cwd
目标进程的工作目录。
可用性
launch.json
✔️settings.json
❌launchSettings.json
✔️ 作为workingDirectory
Args
这些是将传递给您的程序的参数。
可用性
launch.json
✔️settings.json
❌launchSettings.json
✔️ 作为commandLineArgs
在入口点停止
如果需要在目标的入口点停止,您可以选择将 stopAtEntry
设置为 "true"。
可用性
launch.json
✔️settings.json
✔️ 作为csharp.debug.stopAtEntry
launchSettings.json
❌
启动 Web 浏览器
ASP.NET Core 项目的默认 launch.json
模板(截至 C# 扩展 v1.20.0)使用以下配置,以便在 ASP.NET 启动时让 VS Code 启动 Web 浏览器
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
}
关于此的注意事项
-
如果您不希望浏览器自动启动,只需删除此元素即可(如果您的
launch.json
改用launchBrowser
元素,则删除该元素)。 -
此模式使用 ASP.NET Core 写入控制台的 URL 启动 Web 浏览器。如果您想修改 URL,请参阅指定浏览器的 URL。如果目标应用程序在另一台机器或容器上运行,或者如果
applicationUrl
具有特殊的 hostname(例如:"applicationUrl": "http://*:1234/"
),这可能会很有用。 -
serverReadyAction
是 VS Code 的一项新功能。相比于内置在 C# 扩展调试器中的旧的launchBrowser
功能,它更推荐使用,因为它可以在 C# 扩展在远程机器上运行时工作,它使用为 VS Code 配置的默认浏览器,并且还允许使用脚本调试器。如果这些功能对您都不重要,您可以继续使用launchBrowser
。如果您想运行特定程序而不是启动默认浏览器,您也可以继续使用launchBrowser
。 -
有关
serverReadyAction
的更多文档可在 Visual Studio Code 2019 年 2 月发行说明 中找到。 -
此工作方式是 VS Code 抓取输出到控制台的内容。如果某一行与模式匹配,它将针对模式“捕获”的 URL 启动浏览器。
以下是对模式作用的解释
\\b
:匹配单词边界。请注意,\b
表示单词边界,但因为这在 json 字符串中,所以\
需要转义,因此是\\b
。Now listening on:
:这是一个字符串字面值,意味着后续文本必须是Now listening on:
。\\s+
:匹配一个或多个空格字符。(
:这是一个“捕获组”的开始。它指示要保存并用于启动浏览器的文本区域。http
:字符串字面值。s?
:字符s
或没有。://
:字符串字面值。\\S+
:一个或多个非空白字符。)
:捕获组的结束。
-
这两种形式的浏览器启动都需要
"console": "internalConsole"
,因为浏览器启动器会抓取目标进程的标准输出来知道 Web 服务器何时初始化完毕。
指定浏览器的 URL
如果您想忽略控制台输出中的 URL,可以从模式中删除 (
和 )
,并将 uriFormat
设置为您想要启动的内容。
示例
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+https?://\\S",
"uriFormat": "http://localhost:1234"
}
如果您想使用控制台输出中的端口号,但不使用 hostname,您也可以使用类似以下内容
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+http://\\S+:([0-9]+)",
"uriFormat": "http://localhost:%s"
}
实际上,您可以打开几乎任何 URL,例如,您可以通过这样做打开默认的 swagger ui
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+http://\\S+:([0-9]+)",
"uriFormat": "http://localhost:%s/swagger/index.html"
}
注意:您需要确保您的项目已设置 swaggerui 才能执行此操作。
可用性
launch.json
✔️settings.json
❌launchSettings.json
✔️,使用launchBrowser
和applicationUrl
环境变量
可以使用此架构将环境变量传递给您的程序
"env": {
"myVariableName":"theValueGoesHere"
}
可用性
launch.json
✔️settings.json
❌launchSettings.json
✔️ 作为environmentVariables
控制台(终端)窗口
"console"
设置控制目标应用程序启动到哪个控制台(终端)窗口。它可以设置为以下任一值 --
"internalConsole"
(默认):目标进程的控制台输入 (stdin) 和输出 (stdout/stderr) 通过 VS Code 调试控制台路由。此模式的优点是您可以在一个地方看到来自调试器和目标程序的消息,因此不会错过重要消息或需要来回切换。这对于具有简单控制台交互的程序很有用(例如:使用Console.WriteLine
和/或Console.ReadLine
)。当目标程序需要完全控制控制台时,例如更改光标位置、使用Console.ReadKey
进行输入的程序等,则不应使用此模式。有关向控制台输入内容的说明,请参阅下文。"integratedTerminal"
:目标进程将在 VS Code 的集成终端内运行。选择编辑器下方的选项卡组中的终端选项卡与您的应用程序进行交互。使用此模式时,默认情况下,启动调试时不会显示调试控制台。如果使用launch.json
,可以使用internalConsoleOptions
进行配置。"externalTerminal"
:目标进程将在其自己的外部终端中运行。使用此模式时,您需要在 Visual Studio Code 和外部终端窗口之间切换焦点。
可用性
launch.json
✔️settings.json
✔️ 作为csharp.debug.console
launchSettings.json
❌
注意:
csharp.debug.console
设置仅用于使用dotnet
调试配置类型启动的控制台项目。
使用 internalConsole 时向目标进程输入文本
使用 internalConsole
时,您可以在 Visual Studio Code 中输入文本,这些文本将由 Console.ReadLine
和其他从 stdin
读取的类似 API 返回。为此,在程序运行时,将文本输入到调试控制台底部的输入框中。按下 Enter 将文本发送到目标进程。请注意,如果在程序在调试器下停止时在此框中输入文本,此文本将被评估为 C# 表达式,而不是发送到目标进程。
示例
launchSettingsProfile
和 launchSettingsFilePath
虽然对 launchSettings.json
的完全支持需要使用类型为 "type": "dotnet"
的启动配置,但 coreclr
和 clr
调试器类型也支持 launchSettings.json
功能的有限子集。这对于希望在 Visual Studio Code 和完整 Visual Studio 中使用相同设置的用户很有用。
要配置使用哪个 launchSettings.json
配置文件(或阻止使用它),请设置 launchSettingsProfile
选项
"launchSettingsProfile": "ProfileNameGoesHere"
例如,这将使用此示例 launchSettings.json
文件中的 myVariableName
{
"profiles": {
"ProfileNameGoesHere": {
"commandName": "Project",
"environmentVariables": {
"myVariableName": "theValueGoesHere"
}
}
}
}
如果未指定 launchSettingsProfile
,将使用第一个包含 "commandName": "Project"
的配置文件。
如果 launchSettingsProfile
设置为 null/空字符串,则 Properties/launchSettings.json
将被忽略。
默认情况下,调试器将在 {cwd}/Properties/launchSettings.json
中搜索 launchSettings.json
。要自定义此路径,请设置 launchSettingsFilePath
"launchSettingsFilePath": "${workspaceFolder}/<Relative-Path-To-Project-Directory/Properties/launchSettings.json"
限制
- 仅支持包含
"commandName": "Project"
的配置文件。 - 仅支持
environmentVariables
、applicationUrl
和commandLineArgs
属性 launch.json
中的设置将优先于launchSettings.json
中的设置,例如,如果launch.json
中args
已设置为非空字符串/数组,则launchSettings.json
内容将被忽略。
可用性
launch.json
✔️settings.json
❌launchSettings.json
❌
源文件映射
您可以选择使用此形式提供映射来配置如何打开源文件
"sourceFileMap": {
"C:\\foo":"/home/me/foo"
}
在此示例中
C:\foo
是编译模块(例如:MyCode.dll)时一个或多个源文件(例如:program.cs
)的原始位置。它可以是包含源文件的目录,也可以是源文件的完整路径(例如:c:\foo\program.cs
)。它不必存在于运行 Visual Studio Code 的计算机上,如果您正在进行远程调试,也不必存在于远程机器上。调试器从.pdb
(符号)文件中读取源文件路径,并使用此映射转换路径。/home/me/foo
是 Visual Studio Code 现在可以找到源文件的路径。
可用性
launch.json
✔️settings.json
✔️ 作为csharp.debug.sourceFileMap
launchSettings.json
❌
仅我的代码
您可以选择将 justMyCode
设置为 "false" 来禁用它。当您尝试调试从某个库(该库没有符号或已优化)中拉取的代码时,应禁用“仅我的代码”。
"justMyCode":false
“仅我的代码”是一组功能,通过隐藏您可能正在使用的优化库(如 .NET Framework 本身)的一些详细信息,使您可以更轻松地专注于调试自己的代码。此功能最重要的子部分是 --
- 用户未处理的异常:在异常即将被框架捕获之前自动停止调试器
- 仅我的代码单步执行:在单步执行时,如果框架代码回调到用户代码,则自动停止。
可用性
launch.json
✔️settings.json
✔️ 作为csharp.debug.justMyCode
launchSettings.json
❌
需要精确源文件
调试器要求 pdb 和源代码完全相同。要更改此设置并禁用源文件必须相同的限制,请添加
"requireExactSource": false
可用性
launch.json
✔️settings.json
✔️ 作为csharp.debug.requireExactSource
launchSettings.json
❌
单步跳入属性和运算符
调试器默认在托管代码中单步跳过属性和运算符。在大多数情况下,这提供了更好的调试体验。要更改此设置并启用单步跳入属性或运算符,请添加
"enableStepFiltering": false
可用性
launch.json
✔️settings.json
✔️ 作为csharp.debug.enableStepFiltering
launchSettings.json
❌
日志记录
您可以选择启用或禁用应记录到输出窗口的消息。logging 字段中的标志包括:'exceptions'、'moduleLoad'、'programOutput'、'browserStdOut' 和 'consoleUsageMessage'。
在 'logging.diagnosticsLog' 下还有高级选项,用于诊断调试器问题。
可用性
launch.json
✔️settings.json
✔️ 在csharp.debug.logging
下launchSettings.json
❌
管道传输
如果需要调试器使用另一个可执行文件连接到远程计算机,以在 VS Code 和 .NET Core 调试器后端 (vsdbg) 之间中继标准输入和输出,请按照此架构添加 pipeTransport 字段
"pipeTransport": {
"pipeProgram": "ssh",
"pipeArgs": [ "-T", "ExampleAccount@ExampleTargetComputer" ],
"debuggerPath": "~/vsdbg/vsdbg",
"pipeCwd": "${workspaceFolder}",
"quoteArgs": true
}
有关管道传输的更多信息可在此处找到。
您可以在此处找到有关配置 Windows Subsystem for Linux (WSL) 管道传输的信息。
可用性
launch.json
✔️settings.json
❌launchSettings.json
❌
特定于操作系统的配置
如果需要根据不同的操作系统更改特定命令,可以使用字段:'windows'、'osx' 或 'linux'。您可以替换上述任何字段以适用于特定操作系统。
禁止 JIT 优化
.NET 调试器支持以下选项。如果为 true,当优化的模块(在 Release 配置中编译的 .dll)加载到目标进程中时,调试器将要求即时编译器生成禁用优化的代码。此选项默认为 false。
"suppressJITOptimizations": true
.NET 中的优化如何工作: 如果您尝试调试代码,当代码未优化时会更容易。这是因为当代码经过优化时,编译器和运行时会更改生成的 CPU 代码,使其运行速度更快,但与原始源代码的映射不再那么直接。这意味着调试器经常无法告诉您局部变量的值,并且代码单步执行和断点可能无法按预期工作。
通常,Release 构建配置会创建优化的代码,而 Debug 构建配置则不会。Optimize
MSBuild 属性控制是否告知编译器优化代码。
在 .NET 生态系统中,代码从源文件转换为 CPU 指令是一个两步过程:首先,C# 编译器将您输入的文本转换为称为 MSIL 的中间二进制形式,并将其写入 .dll 文件。之后,.NET Runtime 将此 MSIL 转换为 CPU 指令。这两个步骤都可以在一定程度上进行优化,但由 .NET Runtime 执行的第二步会进行更显著的优化。
此选项的作用: 此选项控制当已启用优化编译的 DLL 加载到目标进程内时会发生什么。如果此选项为 false(默认值),则当 .NET Runtime 将 MSIL 代码编译为 CPU 代码时,它会保留优化。如果选项为 true,则调试器会请求禁用优化。
何时应使用此选项: 当您从其他来源(例如 nuget 包)下载了 dll 并希望调试此 DLL 中的代码时,应使用此选项。为了使其工作,您还必须找到此 DLL 的符号 (.pdb) 文件。
如果您只对调试本地构建的代码感兴趣,最好将此选项保留为 false,因为在某些情况下,启用此选项会显著减慢调试速度。减速有两个原因 --
- 优化的代码运行速度更快。如果您关闭大量代码的优化,所需时间会累积。
- 如果启用了“仅我的代码”,调试器甚至不会尝试加载已优化 dll 的符号。查找符号可能需要很长时间。
此选项的限制: 在两种情况下,此选项将不起作用
1:在将调试器附加到已在运行的进程的情况下,此选项对调试器附加时已加载的模块没有影响。
2:此选项对已预编译(ngen'ed)为本地代码的 dll 没有影响。但是,您可以通过将环境变量 COMPlus_ReadyToRun
设置为 0
来启动进程,从而禁用预编译代码的使用。如果您的目标是旧版本的 .NET Core (2.x),请同时将 COMPlus_ZapDisable
设置为 '1'。如果您在调试器下启动,可以通过将此设置添加到 launch.json
中来配置此项
"env": {
"COMPlus_ZapDisable": "1",
"COMPlus_ReadyToRun": "0"
}
可用性
launch.json
✔️settings.json
✔️ 作为csharp.debug.suppressJITOptimizations
launchSettings.json
❌
符号选项
symbolOptions
元素允许自定义调试器搜索符号的方式。示例
"symbolOptions": {
"searchPaths": [
"~/src/MyOtherProject/bin/debug",
"https://my-companies-symbols-server"
],
"searchMicrosoftSymbolServer": true,
"searchNuGetOrgSymbolServer": true,
"cachePath": "/symcache",
"moduleFilter": {
"mode": "loadAllButExcluded",
"excludedModules": [ "DoNotLookForThisOne*.dll" ]
}
}
属性
searchPaths:符号服务器 URL(例如:https://msdl.microsoft.com/download/symbols
)或目录(例如:/build/symbols)数组,用于搜索 .pdb
文件。除了默认位置(模块旁边和 .pdb
最初存放的路径)之外,还将搜索这些目录。
searchMicrosoftSymbolServer:如果为 true
,则将 Microsoft 符号服务器 (https://msdl.microsoft.com/download/symbols) 添加到符号搜索路径。如果未指定,此选项默认为 false
。
searchNuGetOrgSymbolServer:如果为 true
,则将 Nuget.org 符号服务器 (https://symbols.nuget.org/download/symbols) 添加到符号搜索路径。如果未指定,此选项默认为 false
。
cachePath:从符号服务器下载的符号应缓存到的目录。如果未指定,在 Windows 上调试器默认为 %TEMP%\\SymbolCache
,在 Linux 和 macOS 上调试器默认为 ~/.dotnet/symbolcache
。
moduleFilter.mode:此值可以是 "loadAllButExcluded"
或 "loadOnlyIncluded"
。在 "loadAllButExcluded"
模式下,调试器加载所有模块的符号,除非该模块在 'excludedModules' 数组中。在 "loadOnlyIncluded"
模式下,除非模块在 'includedModules' 数组中,或者通过 'includeSymbolsNextToModules' 设置包含,否则调试器不会尝试加载任何模块的符号。
loadAllButExcluded 模式的属性
moduleFilter.excludedModules:调试器不应加载符号的模块数组。支持通配符(例如:MyCompany.*.dll)。
loadOnlyIncluded 模式的属性
moduleFilter.includedModules:调试器应加载符号的模块数组。支持通配符(例如:MyCompany.*.dll)。
moduleFilter.includeSymbolsNextToModules:如果为 true,对于不在 'includedModules' 数组中的任何模块,调试器仍将检查模块本身旁边和启动可执行文件旁边,但不会检查符号搜索列表中的路径。此选项默认为 'true'。
可用性
launch.json
✔️settings.json
✔️ 在csharp.debug.symbolOptions
下launchSettings.json
❌
Source Link 选项
Source Link 是一项功能,当您调试在另一台计算机上构建的代码(例如来自 nuget 包的代码)时,调试器可以通过从 Web 下载匹配的源代码来自动显示。为了实现此功能,您正在调试的代码的 .pdb 文件包含将 DLL 中的源文件映射到调试器可以下载的 URL 的数据。有关 Source Link 的更多信息,请访问 https://aka.ms/SourceLinkSpec。
launch.json
中的 sourceLinkOptions
元素允许按 URL 自定义 Source Link 行为。它是一个从 URL 到该 URL 的 Source Link 选项的映射。URL 名称中支持通配符。目前唯一的自定义是是否为该 URL 启用了 Source Link,但将来可能会添加更多选项。
示例
"sourceLinkOptions": {
"https://raw.githubusercontent.com/*": { "enabled": true },
"*": { "enabled": false }
}
此示例启用 GitHub URL 的 Source Link,并禁用所有其他 URL 的 Source Link。
此选项的默认值是为所有 URL 启用 Source Link。同样,对于 sourceLinkOptions
映射中没有规则的任何 URL,也会启用 Source Link。
要禁用所有 URL 的 Source Link,请使用 "sourceLinkOptions": { "*": { "enabled": false } }
。
如果多个条目覆盖同一 URL,则使用更具体的条目(字符串长度更长的条目)。
目前,Source Link 仅适用于无需身份验证即可访问的源文件。因此,例如,调试器可以从 GitHub 上的开源项目下载源文件,但无法从私有 GitHub 仓库或 Visual Studio Team Services 下载。
可用性
launch.json
✔️settings.json
❌launchSettings.json
❌
目标架构选项 (macOS M1)
Apple M1 上的 .NET 支持 x86_64 和 ARM64。调试时,调试器附加到的进程架构和调试器架构必须匹配。如果它们不匹配,可能会导致 Unknown Error: 0x80131c3c
。
扩展会尝试根据 PATH 中 dotnet --info
的输出来解析 targetArchitecture
,否则会尝试使用与 VS Code 相同的架构。
您可以通过在 launch.json
中设置 targetArchitecture
来覆盖此行为。
示例
"targetArchitecture": "arm64"
可用性
launch.json
✔️settings.json
❌launchSettings.json
❌
检查 DevCert
此选项控制在启动时,调试器是否应检查计算机是否具有用于开发运行在 https 终结点上的 Web 项目的自签名 HTTPS 证书。为此,它会尝试运行 dotnet dev-certs https --check --trust
,如果未找到证书,它将提示用户建议创建一个。如果经用户批准,该扩展将运行 dotnet dev-certs https --trust
来创建一个受信任的自签名证书。
如果未指定,当设置了 serverReadyAction
时,此项默认为 true。此选项在 Linux、VS Code 远程和 VS Code for the Web 场景下无效。
你可以在 launch.json
中将 checkForDevCert
设置为 false 来替代此行为。
示例
"checkForDevCert": "false"
可用性
launch.json
✔️settings.json
❌launchSettings.json
✔️ 对应useSSL