新增一个C#工程,用记事本打开工程文件(.csproj结尾),滚动条拉到最后,大家可以看到一段如下的代码,其中<Target Name="BeforeBuild">和<Target Name="AfterBuild">大家根据名字也就可以看出,在编译前后似乎可以做些什么,不着急慢慢来。

<Project>......<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /><!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.<Target Name="BeforeBuild"></Target><Target Name="AfterBuild"></Target>-->
</Project>

首先了解下MSBuild 项目文件架构引用,这里介绍了这些烦人的XML节点的定义。

http://msdn.microsoft.com/zh-cn/library/5dy88c2e.aspx

另外一些MS封装好的任务我们也浏览下

http://msdn.microsoft.com/zh-cn/library/7z253716.aspx

这里的任务我们就可以直接在  <Target></Target>中使用了,例如我们想在编译后执行一个拷贝任务,就可以这样写:

<Project>......<ItemGroup><CopySourceFiles Include="copyTest.txt" /></ItemGroup><ItemGroup /><PropertyGroup><TargetFolder>bin\Debug</TargetFolder></PropertyGroup><Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /><!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.<Target Name="BeforeBuild"></Target>--><Target Name="AfterBuild"><Copy SourceFiles="@(CopySourceFiles)" DestinationFolder="$(TargetFolder)" SkipUnchangedFiles="true" /></Target>
</Project>

  这样几句简单的语句就可以在我们每次编译的时候将copyTest.txt拷贝到指定的bin\Debug文件夹下了,当然你也可以说,直接将文件添加的工程,将文件的编译属性改成总是拷贝不就可以 吗,何必这么麻烦,是的这样对于简单的拷贝操作的确不需要这么操作,这里是为了简单介绍下编译任务,何况上面连接地址那么多任务不是简单设置下文件属性就是可以实现的。
  以上任务可以通过各种组合实现更加复杂的任务,可见MSBuild没想象的那么单纯,它不仅是简简单单的只能执行编译操作,他也可以是一个强大的任务引擎。这里有一篇文章比较详细介绍MSBuild:http://blog.csdn.net/mittermeyer/article/details/3839101

不仅如此,我们还可以自定义任务,新建一个类库工程,添加引用Microsoft.Build开头的那些库,自定义的任务就得继承任务接口ITask接口

public interface ITask { IBuildEngine BuildEngine { get; set; } ITaskHost HostObject { get; set; } bool Execute(); }

  当然这个接口看起来实现有些复杂,为了实现一个简单的任务我们可以从实现ITask类的抽象类Task继承,这样我们只需要重写Execute方法即可,以下我们实现一个创建文件夹的目录的任务,首先我们先定义一个目录属性OutPutDir 上面特性[Required]表示这个属性是必须输入的。这样一个简单的MSBuild扩展任务就完成了。

    public class DoTask : Task{private string _OutPutDir;[Required]public string OutPutDir{get { return _OutPutDir; }set { _OutPutDir = value; }}public override bool Execute(){
if(!Directory.Exists(_OutPutDir)){Directory.CreateDirectory(_OutPutDir);}return true;}}

下面看下我们如何调用我们生产的这个任务吧,把生成的dll文件放到我们测试工程下,用记事本打开工程文件在文件最后添加以下节点:

<Project>......<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /><!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.<Target Name="BeforeBuild"></Target>--><UsingTask TaskName="DoTask" AssemblyFile="MSTaskExtensionTest.dll"/><Target Name="AfterBuild"><DoTask OutPutDir="$(MSBuildProjectDirectory)\HelloWorld"/></Target>
</Project>

使用UsingTask对我们的任务进行引用,其中TaskName为我们定义的任务名称,AssemblyFile为我们任务编译后的dll文件地址,

其中有一句$(MSBuildProjectDirectory),这个是对当前工程文件目录的引用,更多引用:

MSBuildProjectDirectory : 项目文件所在目录的绝对路径,例如,C:/MyCompany/MyProduct。
MSBuildProjectFile           : 项目文件的完整文件名(包括文件扩展名),例如,MyApp.proj。
MSBuildProjectExtension : 项目文件的文件扩展名(包括点号),例如,.proj。
MSBuildProjectFullPath   : 项目文件的绝对路径和完整文件名,例如,C:/MyCompany/MyProduct/MyApp.proj。
MSBuildProjectName       : 项目文件的文件名(不包括文件扩展名),例如,MyApp。
MSBuildBinPath               : 当前使用的 MSBuild 二进制文件所在目录的绝对路径。
MSBuildProjectDefaultTargets : Project元素的 DefaultTargets 属性中指定的目标的完整列表。
MSBuildExtensionsPath  : MSBuild 文件夹位于 Program Files 目录下。此位置用于存放自定义目标文件。

参考:http://blog.csdn.net/livelylittlefish/article/details/3410733

最后查看我们任务运行后截图吧:

HelloWorld就是我们编译后使用自定义任务生成的文件夹。现在我们可以随心所欲进行更复杂的任务了...

转载于:https://www.cnblogs.com/guanglin/p/3161216.html

MSBuild编译扩展相关推荐

  1. php自己编译扩展,Linux编译PHP添加扩展库的方法

    在编译PHP的时候除了必要的目录指定,好多参数都没有加--等我在安装web程序的时候,才发现,很多参数是要加上的,但是我lnmp已经搭建好了,也不想重新编译,重新安装..于是就在网上找到了此文 一.添 ...

  2. Windows下编译扩展OpenCV 3.1.0 + opencv_contrib

    在Windows下编译扩展OpenCV 3.1.0 + opencv_contrib 为什么要CMake,这里我陈述自己的想法,作为一个刚使用opencv库的小白来说,有以下大概三点内容 1.由于在学 ...

  3. msbuild 语法_如何通过命令行 msbuild 编译项目

    本文告诉大家如何通过 msbuild 编译一个项目,通过命令行编译可以输出更多的编译信息,可以用来调试自己写的编译相关方法,可以看到是哪个文件编译失败 在开始菜单可以找到 VisualStudio 的 ...

  4. OpenWrt编译扩展机制feeds

    传统的Linux操作系统在编译某一个软件的时候,会检查其依赖软件及头文件是否存在,如果没有安装,则会报缺少头文件或缺少链接库等错误,编译将退出.这种机制使得开发者在编译一个软件之前,需要查找该软件所需 ...

  5. 关于msbuild 编译.net 4.5新语法错误的解决方法

    .net4.5以前msbuild 是在%windir%/Microsoft.NET/FrameworkXX/vXX目录下,如:C:\Windows\Microsoft.NET\Framework64\ ...

  6. Pytorch 使用不同版本的 cuda,跟使用不同版本的cuda进行编译扩展库,其实TensorFlow也是一样

    在使用 Pytorch 时,由于 Pytorch 和 cuda 版本的更新,可能出现程序运行时需要特定版本的 cuda 进行运行环境支持的情况,如使用特定版本的 cuda 编译 CUDAExtensi ...

  7. 安装了多个php版本,如何编译扩展

    cd /data/php-5.5.35/ext/mysqli  找到安装包目录下面的ext目录 ./configure --with-php-config=/usr/local/php5/bin/ph ...

  8. windows下vscode + code runner + cmake + msbuild.exe搭建C++快速编译环境

    环境准备 安装 visual studio 安装 VS code VS code 安装 code runner 插件 直接编译不通过CMake 无需安装Cmake 通过预设的环境进行编译 这种方法有时 ...

  9. 使用roslyn代替MSBuild完成解决方案编译

    原本我是使用批处理调用 MSBuild 完成解决方案编译的,新版的 MSBuild 在 Visual Studio 2015 会自带安装. 当然在Visual Studio 2015 中,MSBuil ...

最新文章

  1. 《Java: The Complete Reference》等书读书笔记
  2. 虚拟机安装CentOS以及SecureCRT设置【完美无错版】
  3. (二)深入浅出图解Git,入门到精通(保姆级教程)
  4. LeetCode 4 两个排序数组的中位数
  5. linux 开机启动 自启动 设置
  6. 【正一专栏】卡卡退役-送别了多少人的青春和初恋
  7. php each函数二维数组,PHP特定函数foreach遍历一二维数组
  8. 蚂蚁金服 TRaaS 技术风险防控平台解密
  9. 用友u8数据库表结构
  10. 本土黑马谈车载语音识别 - 汽车电子 - 电子发烧友网
  11. nodejs爬虫基础(二)
  12. Hibernate 与 Mybatis 如何共存?打破你的认知!
  13. pathway一些网站
  14. 银行卡号- 查询银行卡信息
  15. 解密!区块链BaaS是什么?
  16. c语言名人名言大全摘抄,语文摘抄名人名言
  17. 大数据工程师和数据分析师有何区别
  18. 借鉴-牛人开发的网络搜索工具
  19. ajax传递数组类型值到sevrlet
  20. 手动删除百度全家桶流氓软件

热门文章

  1. 程序员 面试笔记 C++ 程序设计的基础 第10章
  2. codeforces 112A-C语言解题报告
  3. SpringBoot —— Bean的注入方式
  4. 实际操作之路考的这些事
  5. 如何减小与“大牛”的差距
  6. 面试风云录(02) - 与顶级CTO交手的难忘经验...
  7. 学习 shell脚本之前的基础知识
  8. PLSQL的表窗口开启(不小心把PLSQL的表窗口关了,在哪里打开)
  9. Python 中使用help()命令后如何退出
  10. 2019南昌网络赛  I. Yukino With Subinterval 树状数组套线段树