新增一个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就是我们编译后使用自定义任务生成的文件夹。现在我们可以随心所欲进行更复杂的任务了...

MSBuild编译扩展的更多相关文章

  1. 通过脚本调用MSBuild编译项目时指定Configuration(解決方案配置)和Platform(解決方案平台),Rebuid(重新生成解决方案),Clean(清理解决方案)

    为了方便打包测试,自己PowerShell写了一个编译和发布的脚本,调用msbuild通过命令行来编译当前解决方案 后来发现一个问题,用VS编译解决方案,我通过 项目属性-Build设置 Releas ...

  2. Delphi:MSBuild编译dproj工程

    Delphi之命令行编译工程,传统是用dcc32来编译的,它需要设置一大堆参数. 自Delphi 2007以后,支持MSBuild编译,它直接编译.dproj工程文件,所有编译需要的东西,都已在其中设 ...

  3. 继《在Windows下编译扩展OpenCV 3.1.0 + opencv_contrib》修订

    在之前的<在Windows下编译扩展OpenCV 3.1.0 + opencv_contrib>中有些问题,后来由于时间不是很充足,故现在对其中的问题进行完善,如下所示对红色框框中的相应的 ...

  4. 代码修改之后MSbuild编译不出最新的dll解决方法

    问题: 使用jenkins发布的时候,开发不断反馈自己修改的文件使用jenkins没有发布到测试环境.经过查证发现使用MSBUILD编译的时出现修改的文件编译出的日期不是最新日期,但是使用VS编译就不 ...

  5. Nginx1.8.1 编译扩展https

    nginx无缝编译扩展https 本贴只限用于通过编译安装的nginx,如果用的是yum源安装请卸载后参见 http://www.cnblogs.com/rslai/p/7851220.html 安装 ...

  6. 如何通过命令行 msbuild 编译项目

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

  7. MSBuild 编译 C# Solution

    Microsoft(R) 生成引擎版本 4.6.1055.0 [Microsoft .NET Framework 版本 4.0.30319.42000] 版权所有 (C) Microsoft Corp ...

  8. Jenkins配置MSBuild编译.net4.6的项目

    经过测试,如果用原始的msbuild,会出现语法无法识别的问题,"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe&qu ...

  9. msbuild 编译指定工程时构建脚本的配置

    有时候 ,我们编译windows的exe时,我们不需要编译所以的工程,我们只需要指定某个工程就好了,此时我们使用/t:工程名:Rebuild(如果要编译全部工程就把工程名去掉,即/t:Rebuild) ...

随机推荐

  1. 【译】 AWK教程指南 4通过文本内容和对比选择指定的记录

    Pattern { Action }为awk中最主要的语法.若某Pattern的值为真则执行它后面的 Action. awk中常使用"关系表达式" (Relational Expr ...

  2. List 接口以及实现类和相关类源码分析

    List 接口以及实现类和相关类源码分析 List接口分析 接口描述 用户可以对列表进行随机的读取(get),插入(add),删除(remove),修改(set),也可批量增加(addAll),删除( ...

  3. CCF 认证

    题意:字符串替换 string+map的应用 #include<iostream> #include<stdio.h> #include<stdlib.h> #in ...

  4. javascript设计模式7

    链式调用 (function(){ function _$(els){ //... } _$.prototype={ each:function(fn){ for(var i=0,len=this.e ...

  5. 中断——中断描述符表的定义和初始化(一) (基于3.16-rc4)

    1.中断描述符表的定义(arch/x86/kernel/traps.c) gate_desc debug_idt_table[NR_VECTORS] __page_aligned_bss; 定义的描述 ...

  6. Nullable问题

    在代码中经常遇到int? 其实int?是Nullable<int>的简写方式. int到int?转化 int? i=null; int j=0; i=j; int?到int转化 ; int ...

  7. 广州大学华软软件学院——NA视频下载

    准备工具: 360极速浏览器(不要认错图标了): 浏览器视频下载插件: 第一步:安装浏览器插件 1.打开浏览器 2.解压,找到插件文件: 3.把插件拖到浏览器中: 4.添加,然后就完成了插件安装 查看 ...

  8. 基于Qt的P2P局域网聊天及文件传送软件设计

    基于Qt的P2P局域网聊天及文件传送软件设计 zouxy09@qq.com http://blog.csdn.net/zouxy09         这是我的<通信网络>的课程设计作业,之 ...

  9. Java 多线程同步的五种方法

    一.引言 闲话不多说,进入正题. 二.为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常.举个例子 ...

  10. 如果将synthesize省略,语义特性声明为assign retain copy时,自己实现setter和getter方法

    如果将synthesize省略,并且我们自己实现setter和getter方法时,系统就不会生成对应的setter和getter方法,还有实例变量 1,当把语义特性声明为assign时,setter和 ...