诊断 MSBuild 任务故障
当 ToolTask 派生类运行工具进程(如果任务未记录更具体的错误,则会返回非零退出代码)时,会发出 MSB6006
。
识别失败的任务
遇到任务错误时,应首先识别失败的任务。
错误文本会指明工具名称(ToolName 的任务实现提供的易记名称或可执行文件的名称)和数字退出代码。 例如,在 error MSB6006: "custom tool" exited with code 1.
中工具名称为 custom tool
,退出代码为 1
。
若要查找失败的 MSBuild 任务:
在命令行生成中:如果生成配置为包含摘要(默认值),则摘要将如下所示:
Build FAILED. "S:\MSB6006_demo\MSB6006_demo.csproj" (default target) (1) -> (InvokeToolTask target) -> S:\MSB6006_demo\MSB6006_demo.csproj(19,5): error MSB6006: "custom tool" exited with code 1.
此结果表示错误发生在项目
S:\MSB6006_demo\MSB6006_demo.csproj
中名为InvokeToolTask
的目标中文件S:\MSB6006_demo\MSB6006_demo.csproj
第 19 行中定义的任务。在 Visual Studio UI 中:Visual Studio 错误列表的
Project
、File
和Line
列中,提供了相同的信息。
查找更多故障信息
当任务未记录特定的错误时,将发出 MSB6006 错误。 无法记录错误通常是因为未将任务配置为理解它所调用的工具发出的错误格式。
正常情况下的工具通常会向其标准输出或错误流发出一些上下文或错误信息,任务默认捕获并记录此信息。 在出现错误之前,查看日志条目以获取其他信息。 重新运行具有较高日志级别的生成时,可能需要保留此信息。 但愿日志记录中指出的其他上下文或错误显示了问题的根本原因。 否则,你可能需要通过检查作为失败任务输入的属性和项来缩小可能的原因范围。
备注
MSBuild 可识别特定的诊断输出格式。 此格式的详细信息记录在诊断消息的 MSBuild 和 Visual Studio 格式中。
调试任务
调试 MSBuild 任务时,以下是一些常规提示。
- 尽可能缩小重现案例的范围(例如,通过设置
/p:BuildProjectReferences=false
,用一个特定项目或一个特定目标启动 MSBuild),以减少需要处理的代码。 - 使用 MSBuild 命令行选项
/m:1
,以便对单个 MSBuild 进程进行调试。 - 将环境变量
MSBUILDDEBUGONSTART
设置为 1,以在启动时将调试器附加到 MSBuild。 - 在任务的
Execute
方法处设置断点,以逐步完成任务。
调试自定义任务
如果正在为自定义任务编写代码,则可以在任务的 Execute
方法中添加用于调用调试器的调用,从而更轻松地进行调试。 可以使用环境变量检查来屏蔽该代码,这样当用户设置了该环境变量时,任务就会停止,从而让用户有机会进行调试。 可以使用 System.Diagnostics.Debugger.Launch 或 System.Diagnostics.Debugger.Break 在调试器中进行启动或中断。
应确保在自定义任务中添加尽可能多的日志记录,以便用户更轻松地对任务进行调试。 在最终确定故障的根本原因时,这一点非常重要;添加足够的日志代码,以便将来检测和报告该故障模式。
考虑使用 xUnit 为任务设置测试环境。 请参阅使用 dotnet test 和 xUnit 在 .NET Core 中进行 C# 单元测试。 可以将 xUnit 测试配置为使用 MSBuild API,通过模拟项目文件以编程方式来调用 MSBuild,其中包括运行相关任务所需的属性、项目和目标。 在某些情况下,可能需要创建一个模拟生成引擎。 可以在使用 Visual Studio 对自定义 MSBuild 任务进行单元测试中查看示例。
在 .NET SDK 项目中,还可以修改 launchSettings.json 以添加一个特殊的调试配置文件,该配置文件使用本文前面提到的命令行参数和环境变量运行 MSBuild.exe。
"profiles": {
"Debug Build": {
"commandName": "Executable",
"executablePath": "$(MSBuildBinPath)\\MSBuild.exe",
"commandLineArgs": "/p:Configuration=$(Configuration) $(ProjectFileName) /m:1",
"workingDirectory": "$(ProjectDir)"
}
}
如果要在运行时提示附加自己的调试器,请将环境变量 MSBUILDDEBUGONSTART
设置为 2
。 在使用不同的调试器时,比如在 macOS 上没有 Visual Studio 时,这可能会很有帮助。