如何使用 MSBuild Target(Exec)中的控制台输出
我曾经写过一篇文章 如何创建一个基于命令行工具的跨平台的 NuGet 工具包,通过编写一个控制台程序来参与编译过程。但是,相比于 基于 Task 的方式,可控制的因素还是太少了。
有没有什么办法能够让控制台程序也能与 MSBuild Target 之间发生更多的信息交换呢?答案是有的,通过捕获控制台的输出!
捕获控制台输出
如果你喜爱阅读文档,那么答案已经不陌生了,在微软的官方文档 Exec Task 中就已经提及了属性 ConsoleToMSBuild。将此属性设置为 True,将能够捕获控制台输出到 MSBuild 中。(不过据说典型的程序员是不爱看文档的)
那么,捕获的输出去了哪里呢?
我在 如何创建一个基于 MSBuild Task 的跨平台的 NuGet 工具包 中提到了使用 Output 来将 Task 中的参数输出出来。而 Exec 也是这么做的。我们将 ConsoleOutput 输出出来即可。由于这个属性不是 ITaskItem[] 类型的,所以我们只能得到字符串属性,于是只能通过 PropertyName 来接收这样的输出。
<Exec ConsoleToMSBuild="True" Command=""$(NuGetWalterlvToolPath)"">
<Output TaskParameter="ConsoleOutput" PropertyName="OutputOfTheCommand" />
</Exec>
PropertyGroup 转 ItemGroup
如果你需要的只是一个字符串,那看完上一节就已经够了。但如果你希望得到的是一组值(例如新增了一组需要编译的文件),那么需要得到的是 ItemGroup 中的多个值,而不是 PropertyGroup 中的单个值。(如果不太明白 ItemGroup 和 PropertyGroup 之间的差别,不要紧,可以阅读 理解 C# 项目 csproj 文件格式的本质和编译流程。)
MSBuild 还自带了一个 Task,名为 CreateItem,就是从一段字符串创建一组 Item。通过下面这段代码,我们能将上一节捕获到的属性转换成项的集合。
<CreateItem Include="$(OutputOfTheCommand)">
<Output TaskParameter="Include" ItemName="AdditionalCompile" />
</CreateItem>
这样,我们便能够
更加完整的代码可能更具有参考意义,所以我贴在了下面:
<Project>
<Target Name="GenerateAdditionalCode" BeforeTargets="CoreCompile">
<Exec ConsoleToMSBuild="True" Command=""$(NuGetWalterlvToolPath)"">
<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 也是支持换行符分隔的。
参考资料
- How get exec task output with msbuild - Stack Overflow
- Exec Task - Visual Studio - Microsoft Docs
- Empty an MSBuild ItemGroup - Stack Overflow
- What’s New in MSBuild 15 - Visual Studio - Microsoft Docs
- Item Element (MSBuild) - Visual Studio - Microsoft Docs
如何使用 MSBuild Target(Exec)中的控制台输出的更多相关文章
- log4j中Spring控制台输出Debug级信息过多解决方法
log4j中Spring控制台输出Debug级信息过多解决方法 >>>>>>>>>>>>>>>>> ...
- Qt在VS2013或Qt Creator 中的控制台输出方式设置
首先值得注意的是:在写程序的时候,项目保存路径不要涉及到中文,否则容易出错! 一.Qt在VS2013中的控制台输出方式: 注意:这里是而不是Qt Application. 然后直接点击finish即可 ...
- java项目中eclipse控制台输出log4j的信息
最近做的一个hadoop项目中,用MR实现了一个比较复杂的问题,其中的日志信息都是使用的是log4j来处理的.但不知怎么控制台不输出日志信息,只能输出System.out.println()信息,这个 ...
- MFC中添加控制台输出
可以在CWinApp的InitInstance()中调用下面的函数,以生成控制台: #include <io.h> #include <fcntl.h> void InitCo ...
- 如何在 MSBuild Target(Exec)中报告编译错误和编译警告
编译错误和编译警告 MSBuild 的 Exec 自带有错误和警告的标准格式,按照此格式输出,将被识别为编译错误和编译警告. 而格式只是简简单单的 error: 开头或者 warning: 开头.冒号 ...
- Java中从控制台输入数据的几种常用方法
Java中从控制台输入数据的几种常用方法 一.使用标准输入串System.in //System.in.read()一次只读入一个字节数据,而我们通常要取得一个字符串或一组数字 //System.in ...
- 将source类中的属性值赋给target类中对应的属性
/** * 对象的属性值拷贝 * <p> * 将source对象中的属性值赋值到target对象中的属性,属性名一样,类型一样 * <p> * example: * <p ...
- Myeclipse和 eclipse中的控制台汉字横着显示修改
Myeclipse和 eclipse中的控制台汉字横着显示问题的修改 如图: 同一种字体有两种显示方式,比如微软雅黑和@微软雅黑,前一种汉字是竖着显示,后一种汉字是横着显示. 修改方法: prefer ...
- ASP.NET Core 集成测试中通过 Serilog 向控制台输出日志
日志是程序员的雷达,不仅在生产环境中需要,在集成测试环境中也需要,可以在持续集成失败后帮助定位问题.与生产环境不同,在集成测试环境中使用控制台输出日志更方便,这样可以通过持续集成 runner 执行 ...
随机推荐
- 使用location.hash保存页面状态
hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分). 语法 location.hash 在我们的项目中,有大量ajax查询表单+结果列表的页面,由于查询结果是a ...
- 又是新动作!微信小程序专属二维码出炉
又到了晚上,微信又给我们带来了惊喜,并这次不是新的能力,而是把大家再熟悉不过的二维码换了新的造型. 正式揭晓:微信特制的小程序码.扫一扫新二维码 只要你的微信升级到了 6.5.7 版本,就可以扫码或者 ...
- Opentsdb简介(一)
原文:http://www.jianshu.com/p/0bafd0168647 1.OpenTSDB介绍 1.1.OpenTSDB是什么?主要用途是什么? 官方文档这样描述:OpenTSDB is ...
- ubuntu 安装包过程中遇到的一个错误解决办法
错误提示如下: 将会安装下列额外的软件包: libdigest-hmac-perl libqt5test5下列[新]软件包将被安装: libdigest-hmac-perl下列软件包将被升级: lib ...
- 【BZOJ4819】新生舞会(分数规划,网络流)
[BZOJ4819]新生舞会(分数规划,网络流) 题面 BZOJ Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会 买 ...
- 三十二 Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy的暂停与重启
scrapy的每一个爬虫,暂停时可以记录暂停状态以及爬取了哪些url,重启时可以从暂停状态开始爬取过的URL不在爬取 实现暂停与重启记录状态 1.首先cd进入到scrapy项目里 2.在scrapy项 ...
- 从零开始搭建webpack+react开发环境
环境主要依赖版本 webpack@4.8.1 webpack-cli@2.1.3 webpack-dev-server@3.1.4 react@16.3.2 babel-core@6.26.3 bab ...
- RDP协议暴力破解
真实案例|RDP协议暴力破解卷土重来! 作者:aqniu星期六, 七月 2, 20160 背景 RDP(Remote Desktop Protocol)称为“远程桌面登录协议”,即当某台计算机开启 ...
- Map以及其子类
package com.Map; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; i ...
- cookie注入原理及注入检测
通常我们的开发人员在开发过程中会特别注意到防止恶意用户进行恶意的注入操作,因此会对传入的参数进行适当的过滤,但是很多时候,由于个人对安全技术了解的不同,有些开发人员只会对get,post这种方式提交的 ...