前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在 MSBuild 中正确使用 % 来引用每一个项(Item)中的元数据

如何在 MSBuild 中正确使用 % 来引用每一个项(Item)中的元数据

作者头像
walterlv
发布2023-10-22 10:58:15
2730
发布2023-10-22 10:58:15
举报
文章被收录于专栏:walterlv - 吕毅的博客

MSBuild 中写在 <ItemGroup /> 中的每一项是一个 ItemItem 除了可以使用 Include/Update/Remove 来增删之外,还可以定义其他的元数据(Metadata)。

使用 % 可以引用 Item 的元数据,本文将介绍如何正确使用 % 来引用每一个项中的元数据。


定义 Item 的元数据

就像下面这样,当引用一个 NuGet 包时,可以额外使用 Version 来指定应该使用哪个特定版本的 NuGet 包。这里的 VersionPrivateAssets 就是 PackageReference 的元数据。

1 2 3 4 5 6

<ItemGroup> <PackageReference Include="dotnetCampus.Configurations.Source" Version="1.0.0" PrivateAssets="All" /> <PackageReference Include="dotnetCampus.CommandLine.Source" Version="1.2.1" PrivateAssets="All" /> <PackageReference Include="Walterlv.Win32.Source" Version="0.12.2-alpha" PrivateAssets="All" /> <PackageReference Include="Walterlv.IO.PackageManagement.Source" Version="0.13.2-alpha" PrivateAssets="All" /> </ItemGroup>

我们随便创建一个新的 Item,也可以定义自己的元数据。

1 2 3 4

<ItemGroup> <_WalterlvItem Include="欢迎访问" Url="https://" /> <_WalterlvItem Include="吕毅的博客" Url="blog.walterlv.com" /> </ItemGroup>

引用元数据

引用元数据使用的是 % 符号。

1 2 3 4 5 6 7

<Target Name="_WalterlvDemo" AfterTargets="AfterBuild"> <ItemGroup> <_WalterlvItem Include="欢迎访问" Url="https://" /> <_WalterlvItem Include="吕毅的博客" Url="blog.walterlv.com" /> </ItemGroup> <Message Text="@(_WalterlvItem):%(Url)" /> </Target>

虽然这里我们只写了一个 Message Task,但是最终我们会输出两次,每一个 _WalterlvItem 项都会输出一次。下面是这段代码的输出:

1 2 3

_WalterlvDemo: 欢迎访问:https:// 吕毅的博客:blog.walterlv.com

当你使用 % 的时候,会为每一个项执行一次这行代码。当然,如果某个 Task 支持传入集合,那么则可以直接收到集合。

如果你不是用的 Message,而是定义一个其他的属性,使用 @(_WalterlvItem):%(Url) 作为属性的值,那么这个属性也会为每一个项都计算一次值。当然最终这个属性的值就是最后一项计算所得的值。

也许可以帮你回忆一下,如果我们不写 %(Url) 会输出什么。当只输出 @(WalterlvItem) 的时候,会以普通的分号分隔的文字。

1 2 3 4 5 6 7

<Target Name="_WalterlvDemo" AfterTargets="AfterBuild"> <ItemGroup> <_WalterlvItem Include="欢迎访问" Url="https://" /> <_WalterlvItem Include="吕毅的博客" Url="blog.walterlv.com" /> </ItemGroup> <Message Text="@(_WalterlvItem)" /> </Target>

会输出:

1 2

_WalterlvDemo: 欢迎访问;吕毅的博客

使用元数据

如果你希望自己处理编译过程,那么可能会对元数据做更多的处理。

为了简单说明 % 的用法,我将已收集到的所有的元数据和它的本体一起输出到一个文件中。这样,后续的编译过程可以直接使用这个文件来获得所有的项和你希望关心它的所有元数据。

1 2 3 4 5 6 7 8 9 10 11 12 13

<PropertyGroup> <_WalterlvContentArgsFilePath>$(IntermediateOutputPath)Args\Content.txt</_WalterlvContentArgsFilePath> <_WalterlvToolFile>$(MSBuildThisFileDirectory)..\bin\compile.exe</_WalterlvContentArgsFilePath> </PropertyGroup> <Target Name="_WalterlvDemo" AfterTargets="AfterBuild"> <ItemGroup> <_WalterlvContentFileLine Include="@(Content)" Line="@(Content)|%(Content.PublishState)|%(Content.CopyToOutputDirectory)" /> </ItemGroup> <WriteLinesToFile File="$(_WalterlvContentArgsFilePath)" Lines="%(_WalterlvContentFileLine.Line)" Overwrite="True" /> <Exec ConsoleToMSBuild="True" Command="&quot;$(_WalterlvToolFile)&quot; PackContent --content-file &quot; $(_WalterlvContentArgsFilePath) &quot;" /> </Target>

这段代码的含义是:

  1. 定义一个文件路径,这个路径即将用来存放所有 Content 项和它的元数据;
  2. 定义一个工具路径,我们即将运行这个路径下的命令行程序来执行自定义的编译;
  3. 收集所有的 Content 项,然后把所有项中的 PublishStateCopyToOutputDirectory 一起拼接成这个样子:
    • Content|PublishState|CopyToOutputDirectory
  4. 写文件,将以上拼接出来的每一项写入到文件中的每一行;
  5. 执行工具程序,这个程序将使用这个文件来执行自定义的编译。

关于使用 exe 进行自定义编译的部分可以参考我的另一篇博客:

关于写文件的部分可以参考我的另一篇博客:

关于项元数据的其他信息

一些已知的元数据:


参考资料

本文会经常更新,请阅读原文: https://blog.walterlv.com/post/how-to-reference-msbuild-item-metadata.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected])

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定义 Item 的元数据
  • 引用元数据
  • 使用元数据
  • 关于项元数据的其他信息
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档