一个典型的.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“,记住我!

天呐!你知道MSBuild都干了些什么相关推荐

  1. 【一周读书】哲学家,你们都干了些什么?

    书籍:<哲学家们都干了些什么> 在读这本书之前,我对哲学的印象是这样的: 哲学似乎和宗教有点关系?似乎在解决人的精神痛苦方面的问题?哲学就是一大堆难懂并且无用的理论!我要是和同学谈哲学肯定 ...

  2. 什么是哲学?《哲学家们都干了些什么?》读后感

    <哲学家们都干了些什么?> 前言 自从听到哲学这两个字开始,其实多年来心中有个问题,对,什么是哲学,哲学有什么用,直到我读了,<哲学家们都干了些什么?>林欣浩,林欣浩 并不是什 ...

  3. 【哲学问题】-《哲学家们都干了些什么?》

    引言 本文来源于<哲学家们都干了些什么?>这本书以及本人阅读此书之后的一些想法.这本书虽通熟易懂,但贯穿了哲学所涉及的大部分内容,我将挑出书中涉及的比较重要的内容并融入我的部分思考分几次来 ...

  4. 西西弗的石头----读《哲学家都干了些什么》有感

    <西西弗的神话>里讲述了一个希腊神话,说西西弗被众神惩罚,把一个巨石推向山顶.但石头一到山顶又会自己滚下来,西西弗必须重复这样的苦役,直到永远.加缪用这个例子来说明我们生活的荒谬. 西西弗 ...

  5. 《哲学家们都干了些什么》读后感

    上帝既然知道亚当和夏娃会偷吃禁果,为什么一开始不去阻止他们? 奥古斯丁的解释是,关键在于自由.上帝给了亚当和人类自由意志,所以也必须让人类拥有作恶的可能. 更具体地说,上帝是善的,而上帝的善表现在上帝 ...

  6. 读书:哲学家们都干了些什么

    哲学本质上是人理解人.人认识人的理性活动,是对世界基本和普遍之问题研究的学科,是关于世界观的理论体系.--百度百科 这本书应该是想用不那么严肃的方式串起整个哲学史,可能有一些地方不那么详实和严谨,但对 ...

  7. 进华为半年我都干了些啥

    楼主目前在华为云搞Java开发,22年8月份入职的.和大家分享下入职半年我都干了些什么事情. 主要分为两个方面. 第一个是业务,华为云是微服务架构,楼主是Java开发和Python开发,进入了其中一个 ...

  8. 哲学家们都干了些什么?

    有道是,人不能闲,人一闲下来,就会胡思乱想.这不,闲得无聊读了一本<哲学家们都干了些什么?>. 谈到哲学,就是思考诸如"人为什么活着?人生的意义是什么?宇宙的本质是什么?&quo ...

  9. 转载:IP-Guard都干了些什么(其他如威盾等亦差不多)

    ##IP-Guard 整个一裹着信息安全软件外衣的超级流氓,下面来看一下它对我们的系统都干了什么. 首先是生成的文件,别看它安装程序那么小,其实生成的文件很多也一点都不小 C:\Program Fil ...

最新文章

  1. mac Hbuilder 无法打开的解决方案
  2. 前端学习总结——CSS布局方式之传统布局
  3. Linux第一条指令地址,arm-linux 启动代码分析——stage1 (1)
  4. Linux服务部署之NTP时间服务器
  5. 列级触发器 SQL Server
  6. django 1.8 官方文档翻译: 2-5-2 进行原始的sql查询
  7. 本模型基于Cruise软件搭建整车模型,基于Matlab/Simulink软件搭建整车控制模块,包括整车模式控制、扭矩分配
  8. linux打jar包命令行,windows下命令行打jar包方法
  9. centos7 安装最新破解(awvs12)Acunetix Vulnerability Scanner12破解和批量导入和利用python删除任务
  10. SnagIt - 官方网站
  11. 种草推荐redis客户端
  12. Unity资源打包(AssetBundle)
  13. 主流区块链浏览器导航
  14. 七步学习法 —— 如何高效学习一项技能
  15. AsPack压缩工具
  16. turtle画樱花树林
  17. OpenInfra Days China 2020大会议程已上线,快来报名参加!
  18. 案例分析——快手百万在线直播
  19. 分享一个可以免费一年的短视频平台照片去水印使用教程
  20. 斯坦福首席人工智能科学家:如何教计算机看懂一张图?

热门文章

  1. 如何彻底卸载MySQL
  2. 写一个简单的 django_post demo
  3. h5c3 part6 flex
  4. springMVC--XML解析
  5. PAT 1042. 字符统计
  6. 利用linux shell自己主动顶贴
  7. Hbase笔记4 java操作Hbase
  8. IUnknown接口QueryInterface函数介绍
  9. 用户帐户控制设置_创建快捷方式以避免用户帐户控制弹出式快捷方式
  10. vue引入postcss-plugin-px2rem,px转rem