从最原始的编译器,逐渐到 Shell 命令组合、Make工具,到现在的针对性 Build 工具,Rake、Ant、MSBuild,甚至于 PowerShell 这样的工具;都为我们软件开发以及系统管理做出了贡献,我甚至不能想象几十年前使用编译器生成程序的复杂步骤(其实就是把 makefile 拆开,相当恐怖)。

  探讨 Make、Ant 以及 MSBuild 无太多意义,甚至从纯技术和扩展性上来说,我认为 MSBuild 弱于 NAnt,但是软件并不是这么简单,之所以深研 MSBuild,M$ 作为后盾让人信任的无奈。

  本文主要讲述 MSBuild 的基本概念,以及如何使用它辅助开发。

  首先我们来看一个最简单的 Build:

<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Welcome>Hello MSBuild!Welcome> Property> <Target Name="Build"> <Message Text="$(Hello)" /> Target> Project>

  假设我们把这个文件保存到 D:\build.proj ,然后在命令行切换工作目录到 D:\,运行 msbuild.exe(msbuild 默认直接运行当前目录下的 *.sln 或 *.*proj 文件),则命令行将会显示详细的 build 信息,当然也包括我们的消息 'Hello MSBuild!' 。

概念

Project
  Project 代表一个 Build,有属性 ToolsVersion、DefaultTargets、 InitialTargets,分别为 依赖的 MSBuild 版本、默认 Build 目标,初始化目标。

Property
  Property 是 MSBuild 中的基本单元,可以理解为变量,我们可以在大多数地方使用它作为 Task 的参数以完成我们预期的目标。
  下面的语句示范如何声明 Property:

<PropertyGroup> <Name Condition="$(Name) == ''">KateName> <WorkPath>D:\WorkspaceWorkPath> PropertyGroup>

这里定义了两个 Property,我们可以使用 $(Name) 和 $(WorkPath) 来引用它们,就和前面的范例一样。
  Property 可以使用 MSBuild 的 /p 参数定义,这里就使用 Condition 属性判断是否存在外部 Name,如果不存在则使用自定义的 "Kate"。

Target
  Target 是 Build 的基本单元,也对应 MSBuild 的 /t 参数,可用参数有 DependOnTargets,代表依赖的目标。

Task
  Task 即任务,Build 的过程就是若干 Task 的执行。上面的 就是 MSBuild 内置的一个 Task,Text 则是参数。
  Task 可以使用 Condition 属性。
  通常情况下,MSBuild 自带的 Task 并不够用,有以下 MSBuild 扩展,可以几乎不需要自己写扩展:
  * MSBuild Community Tasks
  * SDC Tasks Library
  * MSBuild Extension Pack

Item
  我们可以简单的把 Item 理解为 .Net 中的 Dictionary> 类型,内层的字典被称作元数据表。

<ItemGroup> <Table Include="A;B;C;D" /> <Game Include="StarCraft" /> <Game Include="WarCraft" /> <Game Include="CoderCraft" /> <Program Include="MyApp"> <Developer>ZealicDeveloper> <Timestamp>2009-01-01T11:22:33Timestamp> Program> ItemGroup>

为方便理解,我们可以用 C# 来表述上述内容。

var Table = new Dictionary<string,Dictionary<string,string> { {"A", new Dictionary<string,string>}, {"B", new Dictionary<string,string>}, {"C", new Dictionary<string,string>}, {"D", new Dictionary<string,string>} }; var Game = new Dictionary<string,Dictionary<string,string> { {"StarCraft", new Dictionary<string,string>}, {"WarCraft", new Dictionary<string,string>}, {"CoderCraft", new Dictionary<string,string>} } var Program = new Dictionary<string,Dictionary<string,string> { {"MyApp", new Dictionary<string,string> { "Developer", "Zealic", "Timestamp", "2009-01-01T11:22:33" } } };

和使用 Property 不同,Item 有如下用法:
* @(Table) : 直接传递 Item 或展开为 A;B;C;D (视 Task 参数类型而定)。
* @(Table, '+') : 以指定的分隔符展开 Item,结果为 A+B+C+D
* @(Table -> '%(Identity).dll') : 转换 Item 为 A.dll;B.dll;C.dll;D.dll
* %(Program.Developer) : 引用 Program Item 的元数据 "Developer";此外,以这种方式使用 Item 都会导致循环所有 Item 成员。比如 ,会导致三次 Task 调用,分别输出 StarCraft, WarCraft 以及 CoderCraft;Identity 代表 Item 的名称,有关 Item 的更多预定义元数据,请参考 MSDN。

Item 可以使用 Condition 属性。

结语

可能有人会问,既然 MSBuild 和批处理能做的事都差不多,为什么不直接使用批处理呢?

有以下几点原因:

* 与 .Net Framework 紧密集成。
    * 易于扩展:你可以使用任何 CLR 上的语言编写 MSBuild Task 进行扩展。
    * 高效率:多个解决方案/项目可以在一个解决方案中编译,甚至支持多核下的并行编译。
    * 利于诊断:MSBuild 可扩展的日志系统使得 build 过程几乎和白盒没有区别,你可以看到 build 的每一步细节。这也是 VS2003 转到 VS2005 之间最大的转变 - IDE 对编译过程的感知从黑盒转变到白盒。

此外,利用众多第三方 Task,MSBuild 可以完成诸如持续集成、管理服务器、自动化部署等任务,解放我们的时间,让我们可以有更多的时间  Coding 或偷懒 -_-。

了解到这些内容以后,聪明的读者,你是否已经打开一个正在开发的项目的 *.csproj 文件,用文本编辑器看看 MSBuild 究竟有什么魔法呢?

PS:文章写的比较简单,不够全面,有问题请给我妹儿   ,我将详细为你解答。或访问我的 Twitter,里面有不少小技巧。

2009-3-28 Zealic

艾伟:MSBuild 简解相关推荐

  1. 最新版freetextbox(版本3.1.6)在asp.net 2.0中使用简解

    最新版freetextbox(版本3.1.6)在asp.net 2.0中使用简解 2008-10-14 12:21 简介:对于FreeTextBox(版本3.1.6)在ASP.Net 2.0中使用,只 ...

  2. 最新版FreeTextBox(版本3.1.6)在ASP.Net 2.0中使用简解(提供博客园本地下载)

    来源:cleocn.com 最新版FreeTextBox(版本3.1.6)在ASP.Net 2.0中使用简解(提供博客园本地下载) 简介:对于FreeTextBox(版本3.1.6)在ASP.Net ...

  3. 爬虫5-BeautifulSoup模块简解2

    1.BeautifulSoup简解2 from bs4 import BeautifulSoup import re file = open("./baidu.html",'rb' ...

  4. github-markdown-css 使用简解,markdown文案格式优化(笔记)

    github-markdown-css 使用简解,markdown文案格式优化 1.npm 安装 $ npm install github-markdown-css 2.使用 导入github-mar ...

  5. Cisco AP1240多SSID配置简解

    Cisco AP1240多SSID配置简解 AP1#show run <?xml:namespace prefix = o ns = "urn:schemas-microsoft-co ...

  6. (转)FFMPEG解码H264拼帧简解

    http://blog.csdn.net/ikevin/article/details/7649095 H264的I帧通常 0x00 0x00 0x00 0x01 0x67 开始,到下一个帧头开始之前 ...

  7. QuickSort简解(分治思想) By ACReaper

    快排又称为快速排序算法 快熟排序主要思想为:递归而分,重于分而治,而简与合. 治: int partition(int A[],int st,int ed){int key = A[st];//把第一 ...

  8. with(nolock)简解

    eg:select top 200 from 表A with(nolock) where 条件 为了性能,查询时不锁定表,从而达到提高查询速度的目的. (转)SQL中with(nolock)详解 大家 ...

  9. RCE代码及命令执行漏洞简解

    在 Web 应用中有时候程序员为了考虑灵活性.简洁性,会在代码调用 代码或命令执行函数去处理.比如当应用在调用一些能将字符串转化成代 码的函数时,没有考虑用户是否能控制这个字符串,将造成代码执行漏 洞 ...

最新文章

  1. FPGA之道(47)时钟及时钟域
  2. map,filter,reduce函数总结
  3. 超图桌面版新建一个简单三维数据集并发布
  4. qt linux 聊天室,Qt网络聊天室客户端
  5. 奈飞文化集:自由与责任_如何与自由客户合作:最好的合同就是您永远不必执行的合同...
  6. matlab基数排序,如何在MATLAB中编写基数排序的程序
  7. mysql自动备份工具 linux_自动备份MYSQL方法 (Linux)
  8. 26留数及其应用(二)
  9. UVa 674 - Coin Change
  10. 洪雅中学成绩2021高考查询,洪雅中学2021年排名
  11. OneNote 安装代码高亮插件 NoteHightlight的安装及使用基础教程
  12. 解决速达软件提示将numeric转换为数据类型numeric时发生算术溢出错误问题
  13. 工行软开和中行软开_工行软开怎么样啊待遇如何,知道的说下啊
  14. srt字幕转ass字幕在线工具分享
  15. GPU硬件加速的原理
  16. 塔科夫服务器修改器,逃离塔科夫修改器+15项
  17. Codeforces:F - Elongated Matrix
  18. 2021-02-17:规定1和A对应、2和B对应、3和C对应...26和Z对应,那么一个数字字符串比如“111”就可以转化为:“AAA“、“KA“和“AK“。给定一个只有数字字符组成的字符串str,请
  19. 使用labelimg标注图片
  20. react-navigation goBack()传值

热门文章

  1. rpt是什么的缩写_rpt是什么意思车上的
  2. visio 新建个人模板
  3. 安卓访客模式_如何设置Android访客模式以及为什么要这么做 | MOS86
  4. solaris 10 ipmp
  5. 探讨:电子商务网站用什么技术开发最好?
  6. Java方法在art虚拟机中的执行
  7. Android 12源码单手模式
  8. Mysql清除表数据的三种方式
  9. 分享平面设计中的视觉思维(技巧实战篇)
  10. sqli-labs第四关