以下过程可帮助你诊断 Visual Studio 项目中的生成问题,并在必要时创建日志以发送到Microsoft进行调查。
忽略属性值
如果项目属性显示为特定值,但该属性对生成没有影响,请执行以下步骤:
打开与 Visual Studio 版本相对应的 Visual Studio 开发人员命令提示符。
在替换解决方案路径、配置和项目名称的值后运行以下命令:
MSBuild /p:SolutionDir="c:\MySolutionDir\";Configuration="MyConfiguration";Platform="Win32" /pp:out.xml MyProject.vcxproj此命令生成“预处理”的 MSBuild 项目文件(out.xml)。 可以搜索该文件以查找特定属性,以查看其定义位置。
属性最后一个定义是构建所使用的。 如果属性设置两次,则第二个值将覆盖第一个值。 此外,MSBuild 还会在多个阶段评估项目:
- 属性组和导入
- 项目定义组
- ItemGroups
- Targets
因此,根据以下顺序:
<PropertyGroup>
<MyProperty>A</MyProperty>
</PropertyGroup>
<ItemGroup>
<MyItems Include="MyFile.txt"/>
</ItemGroup>
<ItemDefinitionGroup>
<MyItems>
<MyMetadata>$(MyProperty)</MyMetadata>
</MyItems>
</ItemDefinitionGroup>
<PropertyGroup>
<MyProperty>B</MyProperty>
</PropertyGroup>
MyMetadata 的值在 B 生成期间对MyFile.txt项进行评价,且其结果不是 A 也不为空。
增量生成比它应生成的更多
如果 MSBuild 不必要地重新生成项目或项目项,请创建详细的或二进制生成日志。 可以在日志中搜索不必要的生成或编译的文件。 输出的内容与以下类似:
Task "CL"
Using cached input dependency table built from:
F:\test\Project1\Project1\Debug\Project1.tlog\CL.read.1.tlog
Outputs for F:\TEST\PROJECT1\PROJECT1\PROJECT1.CPP:
F:\TEST\PROJECT1\PROJECT1\DEBUG\PROJECT1.OBJ
Project1.cpp will be compiled because F:\TEST\PROJECT1\PROJECT1\PROJECT1.H was modified at 6/5/2019 12:37:09 PM.
Outputs for F:\TEST\PROJECT1\PROJECT1\PROJECT1.CPP:
F:\TEST\PROJECT1\PROJECT1\DEBUG\PROJECT1.OBJ
Write Tracking Logs:
Debug\Project1.tlog\CL.write.1.tlog
如果在 Visual Studio IDE 中构建(开启详细输出信息),则 输出窗口 将显示每个项目未更新到最新的原因:
1>------ Up-To-Date check: Project: Project1, Configuration: Debug Win32 ------
1>Project is not up-to-date: build input 'f:\test\project1\project1\project1.h' was modified after the last build finished.
创建详细的日志
- 打开 “工具>选项 ”窗格,然后展开“ 所有设置>项目”和“解决方案>生成和运行 ”部分。
- 打开 “工具>选项 ”对话框,展开“ 项目和解决方案>生成和运行 ”部分。
使用下拉列表,并将 MSBuild 项目生成输出详细程度 和 MSBuild 项目生成日志文件详细 选项都设置为 “详细”。
前一个控件在 输出窗口中 生成详细程度,第二个控件在
{projectname}.log生成过程中在每个项目的中间目录中创建的文件中生成详细程度。在 Visual Studio 开发人员命令提示符下,输入以下命令之一,替换实际路径和配置值:
MSBuild /p:Configuration="MyConfiguration";Platform="x86" /fl MySolution.sln或
MSBuild /p:/p:SolutionDir="c:\MySolutionDir\";Configuration="MyConfiguration";Platform="Win32" /fl MyProject.vcxproj在运行 MSBuild 的目录中创建一个
MSBuild.log文件。
提供 MSBuild 二进制日志以供调查
MSBuild 能够捕获详细的二进制日志文件。 如果遇到生成问题并且能够提供二进制日志,则日志有助于调查问题。
但是,应注意二进制日志中捕获的信息类型,以确保不会无意中共享比你打算的更多。 二进制日志几乎捕获了生成过程中所有内容,包括项目文件的内容和导入的任何文件(如 .props 和 .targets),生成期间运行的所有任务,以及输入输出和已访问的环境变量,这些都在该 MSBuild 会话中被记录。 它通常不包括编译的源文件的内容,但它确实会捕获其全名和路径。
注释
某些生成环境使用环境变量提供机密。 在共享二进制日志之前,请确保它不会公开 API 令牌或其他重要机密。
捕获用于命令行构建的二进制日志
可以通过将 -bl 参数传递给 MSBuild(MSBuild.exe 或 dotnet build) 来创建二进制日志。 可以使用 .binlog或在浏览器中使用实时结构化日志查看器浏览生成的文件的内容。 MSBuild 不会从浏览器中查看的二进制日志中捕获任何数据。
例子
dotnet build -bl
dotnet build -bl:SpecificStep.binlog
MSBuild.exe -bl:ServiceRelease.binlog -p:Configuration=Release
另请参阅 有关二进制日志的更多详细信息。
通过 Visual Studio 捕获二进制日志
捕获所有 MSBuild 调用的日志:
将MSBUILDDEBUGENGINE环境变量设置为'1',并(可选)将MSBUILDDEBUGPATH设置为现有目标文件夹,以存储捕获的日志。 然后,从同一 shell 启动 Visual Studio 以继承环境:
SET MSBUILDDEBUGENGINE=1
SET MSBUILDDEBUGPATH=C:\MSBuildReproLogs
devenv.exe MySolution.sln
$env:MSBUILDDEBUGENGINE = 1
$env:MSBUILDDEBUGPATH="C:\MSBuildReproLogs"
& "devenv.exe" MySolution.sln
然后,将 MSBuild 二进制日志捕获到通过 MSBUILDDEBUGPATH 环境变量指定的位置(默认情况下是当前文件夹的 MSBuild_Logs 子文件夹,或者根据访问权限 %temp%)。
注释
记录每个 MSBuild 调用(包括设计时生成)的日志,并保存在文件夹中,而无需删除较旧的日志-因此日志文件数量可以迅速增长。 建议仅在短时间内设置用于重现问题进行调查的可选环境变量(尽管可以理解的是,一些非确定性的问题可能需要多次尝试重现)。
使用 Project System Tools 扩展创建二进制 MSBuild 日志
请参阅 Project System Tools 存储库中的 本指南 ,了解如何通过 Visual Studio 捕获 binlog。
下载并安装 Project System Tools 扩展。
安装扩展后,某些新项会显示在 “查看>其他 Windows ”菜单中。
选择查看>其他窗口>生成日志记录以显示 Visual Studio 中的生成日志记录窗口。 选择第一个工具栏图标,以开始在项目系统中同时记录常规生成和设计时生成。
记录生成后,它将显示在“生成日志记录”窗口中。 右键单击该项,然后选择上下文菜单上的“ 保存日志 ”以保存
.binlog文件。
可以使用 MSBuild 结构化日志查看器查看和搜索 .binlog 文件。