天呐!你知道MSBuild都干了些什么

一个典型的.NET5.0项目文件是这样的,看着非常简洁:

<Project Sdk="Microsoft.NET.Sdk.Web"><PropertyGroup><TargetFramework>net5.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" /></ItemGroup></Project>

但是,当我们执行“生成”时,却可以看到输出了大量日志,完全不知道这些目标都是哪来的? 

我们知道,生成操作实际是由MSBuild执行的。

那么,MSBuild到底干了什么?

查看日志

虽然,只要你在选项里设置日志级别为“诊断”,项目生成时会输出非常详细的日志记录: 

但是,这样生成的文本日志量太大了,要找出需要的信息难如登天。

这时,我们可以使用“MSBuild结构化日志查看器”,以可视化的方式查看日志。

安装

查看器的安装依赖Chocolatey。

首先,以管理员身份打开命令提示符,运行下列命令安装Chocolatey:

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

然后,运行下列命令安装日志查看器:

choco install msbuild-structured-log-viewer

生成日志

打开MSBuild Structured Log Viewer,选择“Open Project/Solution”,打开我们新建的Web API示例项目WebApplication1.sln,点击“Build”按钮生成日志:

运行完成后,你应该可以看到如下内容:

点击项目名称左边的箭头展开后,可以看到MSBuild准备执行的所有目标,每个目标中包含多个任务:

灰色的表示跳过的目标,展开后可以看到跳过的原因。

下面,我们以bin\Debug\net5.0\Swashbuckle.AspNetCore.Swagger.dll文件怎么输出的为例,演练如何分析日志。

分析日志

Copy任务

在左侧Search Log窗口上方,输入bin\Debug\net5.0\Swashbuckle.AspNetCore.Swagger.dll作为条件:

可以看到文件是由_CopyFilesMarkedCopyLocal目标中的Copy任务生成的,选中后在中间Log窗口双击任务名,会在右侧窗口显示任务详情,原来任务来源于MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets文件。

Copy任务作用是将源文件ReferenceCopyLocalPaths复制到目标文件$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)

那么源文件和目标文件的值,又是从哪来的呢?

OutDir属性

我们可以轻易地查找到$(OutDir)的值等于bin\Debug\net5.0,却没看到bin\Debug\net5.0这个值是由谁赋给它的:

通过左侧的Find In Files窗口,原来它来自于MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets文件,从OutputPath赋值:

metaproj文件

OutputPath的值来源于同一个文件,等于$(BaseOutputPath)$(Configuration)\

BaseOutputPath也来源于这个文件。但奇怪的是,Configuration却来源于一个叫做WebApplication1.sln.metaproj的文件:

项目目录下并没有这个文件啊?!

随后,我们在日志中找到这样一条消息:

已生成元项目“D:\Codes\WebApplication1\WebApplication1.sln.metaproj”。

而且,在WebApplication1.sln.metaproj中,我们还可以找到Rebuild目标:

而Rebuild又依赖于其他目标:

你还记得生成日志时,带的/t:Rebuild参数吗?

现在清楚了,MSBuild启动时首先生成.metaproj文件,然后根据文件中的元数据,按照依赖关系执行目标。

DestinationSubDirectory属性

但是,%(DestinationSubDirectory)在日志里并没有找到任何赋值的位置。

试着继续探索原始文件来源,最终定位到了ResolvePackageAssets目标下的ResolvePackageAssets任务:

具体参数值对应任务的输出参数RuntimeAssemblies

<Output TaskParameter="RuntimeAssemblies" ItemName="RuntimeCopyLocalItems" />

查看dotnet/sdk/Tasks/Microsoft.NET.Build.Tasks/ResolvePackageAssets.cs的源码,RuntimeAssemblies的类型是ITaskItem[]

ITaskItem定义如下:

public interface ITaskItem
{string ItemSpec { get; set; }int MetadataCount { get; }ICollection MetadataNames { get; }IDictionary CloneCustomMetadata();void CopyMetadataTo(ITaskItem destinationItem);string GetMetadata(string metadataName);void RemoveMetadata(string metadataName);void SetMetadata(string metadataName, string metadataValue);
}

接着,我们找到这样一段代码:

if (!string.IsNullOrEmpty(destinationSubDirectory))
{WriteMetadata(MetadataKeys.DestinationSubDirectory, destinationSubDirectory);
}

DestinationSubDirectory原来是Metadata啊!

结论

根据上面的分析,可以梳理出bin\Debug\net5.0\Swashbuckle.AspNetCore.Swagger.dll文件如何输出的整个流程:

  • MSBuild启动,根据项目文件生成.metaproj文件

  • MSBuild根据/t参数, 从.metaproj文件中读取目标

  • 根据目标的依赖关系,按顺序执行其他目标

  • 其中,ResolvePackageAssets目标下的ResolvePackageAssets任务获取项目所有依赖包的Metadata

  • 再由_CopyFilesMarkedCopyLocal目标中的Copy任务遍历依赖包,根据Metadata复制文件到指定目录下的指定文件名

现在,你可以跟同事show一下:我知道MSBuild干了什么!

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/300379.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么理工类专业成绩好的人,英语总是很差?

▲ 点击查看在知乎上曾经有一个话题&#xff1a;为什么会有数学很好但英语很差的人&#xff1f;这个话题还被浏览了四十多万次。说起这个话题&#xff0c;评论中很多人也纷纷表示感同身受。在上学的时候&#xff0c;要么英语成绩好到飞起&#xff0c;要么数学成绩牛逼到不行。…

.Net Core with 微服务 - Polly 服务降级熔断

在我们实施微服务之后&#xff0c;服务间的调用变的异常频繁。多个服务之间可能是互相依赖的关系。某个服务出现故障或者是服务间的网络出现故障都会造成服务调用的失败&#xff0c;进而影响到某个业务服务处理失败。某一个服务调用失败轻则造成当前相关业务无法处理&#xff1…

IfElseActivity

IfElseActivity 1.IfElseActivity有两个IfElseBranch子控件&#xff0c;分别作为IfElse的两个分支容器,系统自动添加&#xff0c; 2.其中左边(为真件条)的IfElseBranch容器要设Condition 3.IfElse左边(为真件条)的IfElseBranch容器的Condition有两个条件模式:Code Condition,De…

荷兰人发明的新客机是劈叉的!乘客坐在机翼上

全世界只有3.14 % 的人关注了青少年数学之旅与汽车外型的复杂多变相比&#xff0c;飞机的外型似乎总是那么朴实无华&#xff0c;不管是客机还是战斗机&#xff0c;大约都是大家习以为常的那个样子……但是&#xff0c;终于有人要推陈出新了&#xff01;荷兰皇家航空公司与代尔夫…

预约 .NET Conf: Focus on F# 活动,赢得官方周边!

James: 最近 .NET 基金会预告了将在本月29日底举行的 .NET Conf: Focus on F# 线上活动&#xff0c;预约这次活动还能有机会赢得官方大礼包。.NET Conf: Focus on F# 是一个免费的、为期一天的直播活动&#xff0c;会上有来自社区和使用f#语言的微软团队的演讲者。学习 F# 如何…

.NET Day in China(上海-今日活动)| 线上线下

点击蓝字关注我们活动简介.NET 6 Preview 6 在 7月14日已经发布&#xff0c;.NET 6 是微软开启全平台统一一个 .NET 计划以来的第一个 LTS 版本&#xff0c;意义重大&#xff0c;微软在 .NET 6 引入了 MAUI&#xff0c;跨平台开发将更为简单&#xff0c;ASP.NET Core 也在不断的…

公司重金求数据分析师:为什么90%的公司都需要它?

全世界只有3.14 % 的人关注了青少年数学之旅混迹互联网的同学们&#xff0c;或多或少都对“数据分析师”这一职业有所耳闻。即使你不认识任何数据分析师&#xff0c;也一定看到过这类研究报告或者文章&#xff1a;Smart is the new sexy. 酷炫的图表&#xff0c;理性的分析阐述…

php配置问题汇总

前两天开始跟进PHP&#xff1b;我觉得&#xff0c;PHP的环境配置远比其他语言的要复杂很多。我所说的“其他语言”&#xff0c;包括Java&#xff0c;Oracle&#xff0c;scala&#xff0c;Python等。到现在PHP的环境被搭好&#xff0c;因为是全手动的配置&#xff0c;我完完整整…

Orchard Core 1.0.0 正式发布!

James: Orchard 最早是微软的员工创造的开源项目&#xff0c;使用的技术架构可以说是非常优秀&#xff0c;源码值得学习。功能也非常强大&#xff0c;支持模块化、多租户、工作流等等功能&#xff0c;可以说是 .NET 世界的 WordPress。一开始是.NET Framework 的&#xff0c;在…

[方法“Boolean Contains(System.Guid)”不支持转换为 SQL]的解决办法

Guid ClsID newGuid("d4ee9c52-8d68-4f33-9485-0926281c78ac");IList<Guid>Ids WebProduct.GetAllChildByID(ClsID);var query db.T_Products.Where(p >Ids.Contains((Guid)p.F_ClsID));//这一句编译时无错&#xff0c;但是一执行&#xff0c;就报错出错信息…

解决IE为7939.com的病毒~

病毒名称&#xff1a;“诡秘下载器”变种CXW&#xff08;Trojan.DL.Delf.cxw&#xff09;病毒类型&#xff1a;流氓软件病毒危害级别&#xff1a;★★★☆该病毒运行后会从***指定的网站下载指令并运行&#xff0c;会将用户IE浏览器的主页锁定为一个名叫“7939上网导航”的网站…

这哥们到底是应聘的还是来收购公司的?| 今日趣图

全世界只有3.14 % 的人关注了青少年数学之旅图源网络&#xff0c;侵权删

Abp太重了?轻量化Abp框架

本文首发于个人博客&#xff08;https://blog.zhangchi.fun/&#xff09;在进行框架的选型时&#xff0c;经常会听到“***框架太重了”之类的声音&#xff0c;比如“Abp太重了&#xff0c;不适合我们...”。事实上&#xff0c;Abp框架真的很重吗&#xff1f;框架的“轻”和“重…

六月赞歌

七月的脚步离我们近了&#xff0c;在六月即将过去的时候我是有些话想说的。今年的6月过得很充实&#xff0c;虽谈不上硕果累累&#xff0c;但至于还是收获颇丰。在这最想提的是生活杂谈小组在几位组长们的激情带动&#xff0c;各组员的热情参与下&#xff0c;站到了小组排行榜的…

避不开的分布式事务

前言关于前面系列的文章已经说到分布式服务之间的通信&#xff0c;则分布式事务接下来就是我们要一起学习的主题&#xff0c;走起。数据库事务在现有大大小小的系统中几乎是避免不开的&#xff0c;或多或少总会有一些业务关联在一块&#xff1b;对于单机事务的应用场景和操作&a…

matlab如何求矩阵的转置矩阵,怎么用MATLAB程序求转置矩阵?急需,高手帮忙………………...

在Matlab下输入&#xff1a;edit&#xff0c;然后将下面两行百分号之间的内容&#xff0c;复制进去&#xff0c;保存%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function ff31(x)f1./[(x-2).^20.1]1./[(x-3).^40.01];%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 返…

任正非一语中的,未来科技的发展核心靠他们!

▲ 点击查看今年6月&#xff0c;华为的任正非接受媒体的采访&#xff0c;多次谈及基础教育&#xff0c;不禁流下了英雄泪&#xff0c;谈话中&#xff0c;曾27次提到了数学&#xff0c;并且表示等自己退休后要找一个好大学&#xff0c;好好地学一学数学。他还谈到了数学对于华…

Windows 2003下×××服务器架设攻略

原文地址[url]http://bbs.51cto.com/thread-49347-1-1.html[/url]Windows 2003下服务器架设攻略笔者有不少朋友因为工作关系常常移动办公&#xff0c;因此资料的传递、与公司信息的及时交流或是累了想在异地打开公司或家里的电脑看看电影等等应用显得很头疼。这方面的应用也就是…

微软出手,蚕食JetBrains系市场?

文 | Travis出品 | OSC开源社区&#xff08;ID&#xff1a;oschina2013&#xff09;近日微软公布了针对 Java 编程语言的 Visual Studio Code 更新路线图&#xff0c;根据路线图的计划&#xff0c;微软将在开发体验、安全、远程开发等方面做出改善。这个更新路线图涵盖了 2021 …

matlab dy,高手,请问用matlab如何解下面方程:y*Dy=a+b*y;我的计算结果里面含有wrightOmega ,怎样解出一般解?...

满意答案weiliyao772013.07.20采纳率&#xff1a;49% 等级&#xff1a;12已帮助&#xff1a;11659人#include #include using namespace std;#define N 20double a[N][N];double x[N1];double b[N1];int n;//n方程个数&#xff0c;n未知数个数int set( ){cout<cin>>…