前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何使用 MSBuild Target(Exec)中的控制台输出

如何使用 MSBuild Target(Exec)中的控制台输出

作者头像
walterlv
发布2018-09-18 12:57:58
2K0
发布2018-09-18 12:57:58
举报

如何使用 MSBuild Target(Exec)中的控制台输出

发布于 2018-06-13 00:08 更新于 2018-09-01 00:03

我曾经写过一篇文章 如何创建一个基于命令行工具的跨平台的 NuGet 工具包,通过编写一个控制台程序来参与编译过程。但是,相比于 基于 Task 的方式,可控制的因素还是太少了。

有没有什么办法能够让控制台程序也能与 MSBuild Target 之间发生更多的信息交换呢?答案是有的,通过捕获控制台的输出!


捕获控制台输出

如果你喜爱阅读文档,那么答案已经不陌生了,在微软的官方文档 Exec Task 中就已经提及了属性 ConsoleToMSBuild。将此属性设置为 True,将能够捕获控制台输出到 MSBuild 中。(不过据说典型的程序员是不爱看文档的

那么,捕获的输出去了哪里呢?

我在 如何创建一个基于 MSBuild Task 的跨平台的 NuGet 工具包 中提到了使用 Output 来将 Task 中的参数输出出来。而 Exec 也是这么做的。我们将 ConsoleOutput 输出出来即可。由于这个属性不是 ITaskItem[] 类型的,所以我们只能得到字符串属性,于是只能通过 PropertyName 来接收这样的输出。

代码语言:javascript
复制
<Exec ConsoleToMSBuild="True" Command="&quot;$(NuGetWalterlvToolPath)&quot;">
  <Output TaskParameter="ConsoleOutput" PropertyName="OutputOfTheCommand" />
</Exec>

PropertyGroup 转 ItemGroup

如果你需要的只是一个字符串,那看完上一节就已经够了。但如果你希望得到的是一组值(例如新增了一组需要编译的文件),那么需要得到的是 ItemGroup 中的多个值,而不是 PropertyGroup 中的单个值。(如果不太明白 ItemGroupPropertyGroup 之间的差别,不要紧,可以阅读 理解 C# 项目 csproj 文件格式的本质和编译流程。)

MSBuild 还自带了一个 Task,名为 CreateItem,就是从一段字符串创建一组 Item。通过下面这段代码,我们能将上一节捕获到的属性转换成项的集合。

代码语言:javascript
复制
<CreateItem Include="$(OutputOfTheCommand)">
  <Output TaskParameter="Include" ItemName="AdditionalCompile" />
</CreateItem>

这样,我们便能够

更加完整的代码可能更具有参考意义,所以我贴在了下面:

代码语言:javascript
复制
<Project>
  <Target Name="GenerateAdditionalCode" BeforeTargets="CoreCompile">
    <Exec ConsoleToMSBuild="True" Command="&quot;$(NuGetWalterlvToolPath)&quot;">
      <Output TaskParameter="ConsoleOutput" PropertyName="OutputOfTheCommand" />
    </Exec>
  </Target>
  <Target Name="_IncludeGeneratedAdditionalCode" AfterTargets="GenerateAdditionalCode">
    <CreateItem Include="$(OutputOfTheCommand)">
      <Output TaskParameter="Include" ItemName="AdditionalCompile" />
    </CreateItem>
    <ItemGroup>
      <Compile Include="@(AdditionalCompile)" />
    </ItemGroup>
    <Message Text="额外添加的编译文件:@(AdditionalCompile)" />
  </Target>
</Project>

CreateItem 的转换分隔符

CreateItem 从属性或字符串转到项是根据分隔符来区分的。由于使用 @(Item) 来获取项时,会得到一个用 ; 分隔的字符串,所以不难想到我们控制台输出的字符串使用 ; 分隔即能满足我们的转换需求。但事实上这是不行的!

因为控制台的转换,每行是有缓冲区限制的,也就是说单行字数不能过多,否则会自动加换行符——这可能导致我们转换成的某一项或者多项中间带了换行符,从而导致错误。

于是,建议直接在控制台程序中使用换行符本身作为分隔符,这样便可以去除这样的限制。因为 CreateItem 也是支持换行符分隔的。


参考资料

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

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

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 如何使用 MSBuild Target(Exec)中的控制台输出
    • 捕获控制台输出
      • PropertyGroup 转 ItemGroup
        • CreateItem 的转换分隔符
        相关产品与服务
        命令行工具
        腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档