付费下载
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、baby_zrqMSBuild的简单介绍与使用MSBuild是Microsoft和Visual Studio的新生成系统。它不仅仅是一个构 造工具,应该称之为拥有相当强大扩展能力的自动化平台。、MSBuild 简介按照笔者现在的理解,MSBuild平台的主要涉及到三部分:执行引擎、构造 工程、任务。其中最核心的就是执行引擎,它包括定义构造工程的规范,解释构 造工程,执行构造动作”构造工程是用来描述构造任务的,大多数情况下我们 使用MSBuild就是遵循规范,编写一个构造工程;MSBuild引擎执行的每一个 构 造动作”就是通过任务实现的,任务就是MSBuild的扩展机制,通过编写新的 任务就能
2、够不断扩充MSBuild的执行能力。所以这三部分分别代表了引擎、脚本和扩展能力。1.1构造工程(脚本文件)先说说构造工程,只要通过Note pad打开任何一个VS2005(也就是支持CLR 2.0)下的C#工程(csproj)文件,就知道构造工程到底是怎么回事了。如果说脚本,我们立刻想到的是 VBScript或者JavaScript,构造工程内描述 的内容,和常见的脚本语言的源文件之间还是有蛮大差距的,为什么也称之为脚 本”呢?因为笔者觉得没啥区别。脚本不就是纯文本形式保存,不经编译解释执 行,可以实现一定逻辑分支的程序么?再看构造工程,在构造工程中我们可以定义和使用变量(通过 Propert
3、y/PropertyGourp/ltem/ltemGroup 等元素),可以使用条件分支(通过 Choose/When/Otherwise等元素)、能够在运行时给变量赋值(通过执行任务,获 取其返回类型参数的方式)、能够定义执行块(通过Target元素,相当于函数)、 能够进行异常处理(通过 On Error元素)、还可以复用已有工程定义的内容(通 过Import元素)。拥有这些能力和高级语言已经相差无几了,所以笔者认为构造 工程不是描述性语言,而是脚本语言。这里还需要强调一点的是,项目级元素(Property)可以在vPropertyGroup> 元素下定义,也可以在构造过程中作为外部
4、参数传入(具体参见 MSBuild命令 行参考)。这是一个非常有用的特性,一般编译时选择配置项( Debug或者 Release就是利用这个特性实现的。有关构造工程的编写规范可以参考MSBuild项目文件引用。1.2执行引擎接下来看执行引擎,通常我们使用下面的命令行开始执行构造:MSBuild.exe vP rojectFile>其中vProjectFile是前面提到的构造工程,也就是脚本文件,那么 MSBuild.exe就应当是执行引擎了。没错,不过看一下源代码就会发现 MSBuild.exe非常简单,其实主要做的工 作就是命令行解析、构造环境的准备(如生成日志记录模块准备一些全局变量
5、), 然后就是创建Microsoft.Build.BuildE ngin e.E ngi ne类的实例,然后调用其 BuildProjectFile方法来完成。所以真正的构造逻辑是在 Microsoft.Build.Engine.dll 中定义并且实现的。下面简单的代码就模拟了MSBuild.exe的工作。view plaincopy to cli pboard print?using System;using System.Collect ion s.Ge neric;using System.Text;using Microsoft.Build.BuildE ngine;n ames pa
6、ce BuildA ProjectCSclass P rogramstatic void Main( stri ng args)/In sta ntiate a new Engine objectEngine engine = new Engin e();/ P oi nt to the path that con tai ns the .NET Framework 2.0 CLR and tools engin e.B inP ath = "c:wi ndows'microsoft. netframeworkv2.0.xxxxx"/ I nsta ntiate a
7、 new FileLogger to gen erate build log FileLogger logger = new FileLogger();/ Set the logfile p arameter to in dicate the log dest in ati on logger. Parameters = "logfile=C:te mpbuild .lo g"/ Register the logger with the engine engin e.RegisterLogger(logger);/ Build a p roject filebool suc
8、cess = engin e.Build ProjectFile("c:te mpvalidate .p roj");/Un register all loggers to close the log file engine.Un registerAIILoggers();if (success)Co nsole.WriteL in e("Build succeeded.");else本文内容主要来源于互联网,文中已尽量引用出处,但仍有疏忽遗漏之处,请原创作者见谅。baby_zrqCon sole.WriteL ine ("Build fail
9、ed. View C:tem pbuild.log for details");具体的对象模型参见CLR类库参考中的Microsoft.Build.Framework命名空 间和Microsoft.Build.BuildEngine 命令空间。笔者简单地分析了一下 MSBuild.exe 和 Microsoft.Build.Engine.dll 的源代码, MSBuild的构造过程大致如下:a)先创建一个构造请求(BuildRequest,构造请求是用来记录构造状态的数 据结构),创建完毕之后将构造请求投递到请求队列中。b)在执行模块中,从请求队列中获取请求,然后开始处理。c)通过P
10、roject类加载构造工程,加载过程中检查是Solution、VC工程还是 其它语言的工程。如果是 Solution的话,生成一个临时的包装工程,逐一构造 Solution中包含的工程;如果是 VC工程的话,也生成一个包装工程,在这个工 程中直接执行VCBuild任务来执行构造。否则直接通过 XmlDocument加载项目 文件,解析其中的元素,识别 Property、Item、Target之类元素。d)工程解析完毕后按照Target的顺序逐一执行。e)在执行Target的过程中先解析是否存在依赖的 Target以及On Error子句 (即产生错误时需要执行的Target)。f)先执行Tar
11、get依赖的Target,然后通过 TaskEngine执行本Target中的每 一个任务。如果Target每一个任务都正确执行的话,那么执行下一个 Target;否 则执行错误处理的Targetg)执行Task的过程就是实例化注册为Task的类,然后调用其Execute方法。h)所有Target执行完毕,则本次构造也执行完毕。以上仅仅为了便于理解概念进行的描述,实际的构造过程可能是考虑到多 CPU以及内联编译,内部逻辑相当复杂,很多地方应用了Proxy模式。1.3 任务(Task)通过对执行引擎的描述可以发现执行引擎主要是维护执行流程以及记录执 行流程中各类变量(Prop erty和Item
12、),具体构造过程中的每一个动作,都是通 过Task实现的。也就是说单靠Microsoft.Build.Engine.dll虽然可以加载并且解析 构造工程,但是无法完成构造动作。之所以MSBuild能够完成编译、链接、创建目录、复制文件等一系列工作,都是因为在Microsoft.Build.Tasks.dll中实现了与之对应的一个个任务。具体请参考MSBuild任务参考以及CLR类库参考 中的Microsoft.Build.Task命名空间通过观察MSBuild自带的这些常用任务,可以发现其中分为两类:一类从 ToolTask继承,这类任务基本上就是直接调用外部二进制文件执行完成某个特定 的动作
13、,例如VCBuild和Exec等;另一类直接从Task继承,是通过内部代码逻 辑完成特定动作,例如Copy和MSBuild等。那些直接执行外部文件的任务虽然 功能强大,但是有比较大的局限性,执行结果的反馈非常有限,通常只有 ExitCode,很难获得其内部执行的更多信息,例如日志输出或者操作影响的结果。大部分情况下我们只需要一个 Exec任务就能够完成全部的构造动作,但是 这样做的结果和我们写一个命令行的批处理文件没什么区别了。MSBuild平台和本文内容主要来源于互联网,文中已尽量引用出处,但仍有疏忽遗漏之处,请原创作者见谅。baby_zrq命令行批处理最大不同在于,它是一个更紧密的工作环境
14、,任务之间通过一系列 自定义的全局参数互相协同工作,比较灵活并且移植性高;同时共享日志模块统 一输出执行过程中的各类信息,便于观察和分析。而批处理中各个命令之间几乎 是完全孤立的,只能通过硬编码的方式进行协同,协作能力比较差。举个最简单的例子,编译三个工程,然后复制编译结果到目标目录下。如果 用批处理可能会写成这个样子:编译工程1、复制编译结果、编译工程2、复制结果、编译工程3、复制结果”而利用MSBuild就可以简化很多工作,例如申明需要编译的工程(工程1、工程2、工程3、.)、编译需要编译的工程、复制 编译结果”在内部直接调用了构造引擎的方 这个例子又一次告诉我们这个世 只是因为他们手中掌
15、握了有效的顺便说一句,MSBuild这个任务比较有趣,法(IBuildEngine2.BuildPrejectFilesInParallel)。界上许多看似强大的东西,其实什么都没有干, 资源。并且实现这种扩展非常方便。ITask接口的类,然后在构造工除了基础的任务之外,任务还可以任意扩展, 创建一个CLR 2.0以上的类库工程,编写实现了程中通过vUsingTask>元素注册任务就可以使用了。例如:view plaincopy to cli pboard print?<Us in gTaskTaskName="Microsoft.Co mp actFramework.B
16、uild.Tasks .P latformVerificati on Task"AssemblyName="Microsoft.CompactFramework.Build.Tasks,Version=, Culture=neutral,P ublicKeyToke n=b03f5f7f11d50a3a" /><Target Name="PI atformVerificati on Task"><P latformVerificati on TaskP latformFamilyName="$(
17、PlatformFamilyName)"P latformlD="$( PlatformID)"SourceAssembly="(I ntermediateAssembly)"Refere nceP ath="(Refere nceP ath)"TreatWarni ngsAsErrors="$(TreatWarni ngsAsErrors)"P latformVersio n="$(TargetFrameworkVersio n)"/></Target><Us
18、 in gTaskTaskName="Microsoft.Co mp actFramework.Build.Tasks .P latformVerificati on Task"AssemblyName="Microsoft.CompactFramework.Build.Tasks,Version=, Culture=neutral,P ublicKeyToke n=b03f5f7f11d50a3a" />vTarget Name="PI atformVerificati on Task"><P lat
19、formVerificati on TaskP latformFamilyName="$( PlatformFamilyName)"P latformlD="$( PlatformID)"SourceAssembly="(l ntermediateAssembly)"Refere nceP ath="(Refere nee Path)"Treatwar nin gsAsErrors="$(TreatWar nin gsAsErrors)"P latformVersio n="$(Tar
20、getFrameworkVersio n)"/></Target>所以说MSBuild能够成为一个构造引擎,不是因为有个叫MSBuild的Exe文件,也不是因为脚本文件被称之为构造工程,而是因为与之配套的 Microsoft.Build.Task.dll中主要实现了主要是和构造相关的任务。换句话说如果提 供和测试相关的任务库的话,MSBuild也就是一个自动测试的平台。总之,MSBuild本身更趋向于一个自动化执行平台,可以根据需求编写不同 的脚本文件来满足不同的应用,当现有能力无法满足时,通过编写新的任务进行 扩展。不仅限于构造,自动安装、自动测试等都可以依赖这个
21、平台来实现。二、MSBuild的简单使用由于MSBuild可以集成多个工具,且任务添加方式可以为加载已有的任务也 可以自己书写新的加载任务或直接使用 Exec任务来执行,故本文只选取一个简 单的任务进行讲解,并不做测试,详细可以在开发端的集成脚本中进行查看。2.1简单项目例子首先写一个简单的C# Con sole程序(你也可以把它改成 VB.NET):/ HelloMSBuild.csusing System;class HelloMSBuildp ublic static void Mai n()Con sole.WriteLi ne("Hello MSBuild!");
22、疋:下面我们就要写一个.csproj文件来控制整个生成过程。值得注意的是,如果 在调用MSBuild.exe时没有指定具体的项目文件,MSBuild引擎会在当前目录下 查找一个名为*.*proj的项目文件。如果你在同一目录中写了多个这样的项目文 件,那么需要手动指定 MSBuild.exe的目标文件,方法是-MSBuild a.cs proj否则MSBuild会提示出错,要求你手动指定目标项目文件。 以下是项目文件:<!- Build.cs proj ->vP roject DefaultTargets="Ru n"> vProperty Bi n=&qu
23、ot;bi n" /> vProperty Out putAssembly="HelloMSBuild" /> vltem Typ e="Source" I nclude="HelloMSBuild.cs" /> vTarget Name="Build"> vTask Name="MakeDir"Directories="$(Bi n)"Co nditio n="!Exists('$(Bi n)')" /&
24、gt;vTask Name="Csc"Sources="(Source)" TargetT yp e="exe" Out pu tAssembly="$(Bi n)$(Out putAssembly).exe" /> v/Target> vTarget Name="R un" De pen dsO nTargets="Build"> vTask Name="Exec"Comma nd="$(Bi n)$(Out putAssem
25、bly).exe" />MSBuildFileFormat,对照上面代码查找相应的v/Target> v/Project> 如果你此前没有过NAnt的开发经验,那么上面这些东西肯定看起来挺吓人。 这个时候最好的办法是打开那篇 项目元素的含义。下面我对其中重要的项目元素进行一下解释。2.2 MSBuild的基本元素2.2.1 P roject 元素这是每一个项目文件的最外层元素,它表示了一个项目的范围。如果缺少了元素,MSBuild会报错称Target兀素无法识别或不被支持。P roject元素拥有多个属性,其中最常用到的是DefaultTargets属性。我们都知道
26、,在一个项目的生成过程中可能需要完成几项不同的任务(比如编译、单元测试、check-in到源代码控制服务器中等),其中每一项任务都可以用Target来Project 的 DefaultTargets(注 比如:表示。对于拥有多个Target的项目,你可以通过设置 意是复数)属性来指定需要运行哪(几)个Targe,vProject DefaultTargets= ” Build ” >或者:vProject DefaultTargets= ” Build;Test;Run如果没有这个设置,MSBuild将只运行排在最前面的那个Target2.2.2 Property 元素在项目中你肯定需要
27、经常访问一些信息,例如需要创建的路径名、最终生成的程序集名称等。这些信息你最好别 hard code进项目中,除非你一次写过之后 永不更改。这时Property就能派上用场了。你把上面提到的那些信息以name/value 的形式添加进Property,随后就可以以$(PropertyName)的形式访问。这样你就无 须为了改动一个文件名称而让整个项目文件伤筋动骨了。比如上面代码中的Bin就是将要创建的路径名称,而 Assembly Name则是最终要生成的程序集名称。 这些属性的名称不是固定的,你完全可以按自己的习惯来进行命名。在使用时, 你需要把属性名称放在” $(和5 )对内(不包括引号)
28、,以表示这里将被替换成一 个Property元素的值。另外,如果Property元素数量比较多,你还可以把它们分门别类地放在不同 的PropertyGroup里,以提高代码的可阅读性。这对Property本身没有任何影响。 比如:vProp ertyGro up>vProperty . />vProperty . />v/Prop ertyGro up> 223 Item 元素在整个项目文件中你肯定要提供一些可被引用的输入性资源 (inp uts)信息, 比如源代码文件、引用的程序集名称、需要嵌入的图标资源等。它们应该被放在 Item里,以便随时引用。语法是:vltem
29、 Type= ” TheType” Include= ” NameOrPath” />其中Type属性可以被看作是资源的类别名称,比如对于.cs源文件,你可以 把它们的Type都设置为Source,对于引用的程序集把Type都设置为Referenee 这样在随后想引用这一类别的资源时只要引用这个Type就可以了,方法旦(TypeName)。可千万别和Property的引用方法弄混了。c#文件都可既然Type是资源的类名,那么Include就是具体的资源名称了,比如在上面 的示例代码中,Include引用的就是C#源代码文件的名称。你也可以用使用通配 符*来扩大引用范围。比如下面这行代码就
30、指定了当前目录下的所有 以通过(Source)来引用:vItem Type= ” Source ” Include= ” *.cs ” />Item放在另外,你也可以通过与PropertyGroup类似的方法把相关的ItemGro up 里。上面已经提到了, 可以包括一个或多个 设置一个Name属性 引用和区别。2.2.4 Target 元素每个 ProjectTargetTarget表示一个需要完成的虚拟的任务单元。Target,从而完成一系列定制的任务。你需要给每个(同一 Project下的两个Target不能拥有同样的Name)以便” Checkout” >举例来说,在你的项
31、目生成过程中可能需要完成三个阶段的任务:首先从 VSS中check-out源代码,接下来编译这些代码并执行单元测试,最后把它们 check-in回VSS。那么通常情况下你可以创建三个不同的 Target以清晰划分三个 不同的阶段:</Target> vTarget Name= <Task Name=” <Task Name=”</Target>vTarget Name=” Build ” DependsOnTargets= ” Checkout”> Build ” ./>UnitTest ” . />本文内容主要来源于互联网,文中已尽量引用
32、出处,但仍有疏忽遗漏之处,请原创作者见谅。baby_zrq<Target Name= ” Check In ” DependsOn Targets= ” CheckOut;Build ”></Target>这样,你就可以非常清晰地控制整个生成过程。 为了反应不同Target之间的 依赖关系(只有Check-in后才能编译,只有编译完成才可能Check-out),你需要设置Target的De pen dsO nTargetsl属性(注意是复数),以表示仅当这些Target 执行完成之后才能执行当前的Target当MSBuild引擎开始执行某项Target时(别 忘了 Pr
33、oject的DefaultTargets属性),会自动检测它所依赖的那些 Target是否已 经执行完成,从而避免因为某个生成环节缺失而导致整个生成过程发生意外。你可以通过Project的DefaultTargets属性指定MSBuild引擎从哪(几)个Target开始执行,也可以在调用 MSBuild.exe时使用t开关来手动指定将要运行的Target,方法如下:MSBuild /tCheckOut这样,只有CheckOut (以及它所依赖的Target,在上文中没有)会被执行。225 Task 元素这可能是整个项目文件中最重要的,因为它才是真正可执行的部分(这也是为什么我在上面说Targe
34、t是虚拟的)。你可以在Target下面放置多个Task来顺序 地执行相应的任务,比如我在上面示例代码中就在两个不同的Target中安排了MakeDir、Csc和Exec三个不同的Task。这些Task通过Name属性来相互区分, 并各自拥有不同的其它属性来完成不同的任务,比如Csc有Sources (源代码文件)、TargetType (目标类型)、OutputAssembly (生成程序集名称)等属性,而 MakeDir则只需设置Directories (需要创建的路径名称列表)即可。也许你会奇怪这些Task的名称和属性从哪里来。好吧,请用文本编译器打 开%windir%Microsoft.
35、NETFrameworkv1230703Microsoft.BuildTasks 文件,看到 了吗?默认情况下里面应该是这样的(不同的版本可能会有细微差别):<!- This file lists all the tasks that ship by default with MSBuild -><DefaultTasks>TaskName="Microsoft.Build.Tasks.NetAssemblyResolver"TaskName="Microsoft.Build.Tasks.Tra nsform Path"<U
36、si ngTask TaskName="Microsoft.Build.Tasks.Csc" AssemblyName="MSBuildTasks"/> <Usi ngTask TaskName="Microsoft.Build.Tasks.MSBuild" AssemblyName="MSBuildTasks"/> <Usi ngTask TaskName="Microsoft.Build.Tasks.Exec" AssemblyName="MSBuildTa
37、sks"/> <Usi ngTask TaskName="Microsoft.Build.Tasks.Vbc" AssemblyName="MSBuildTasks"/> <Usin gTask TaskName="Microsoft.Build.Tasks.MakeDir" AssemblyName="MSBuildTasks"/> <Usin gTask TaskName="Microsoft.Build.Tasks.ResGe n" Assem
38、blyName="MSBuildTasks"/> <Usin gTask TaskName="Microsoft.Build.Tasks.Co py" AssemblyName="MSBuildTasks"/> <Us in gTask AssemblyName="MSBuildTasks"/> <Us in gTask AssemblyName="MSBuildTasks"/> </DefaultTasks>你会注意到,在DefaultTa
39、sks元素下面排列的全是 UsingTask,其中指明每 一个 Task的TaskName (名称)和 AssemblyName (程序集)。比如说第一个 UsingTask就对应着我们上面用过的 Csc任务,它的完整名称(namespace+clas) 本文内容主要来源于互联网,文中已尽量引用出处,但仍有疏忽遗漏之处,请原创作者见谅。是 Microsoft.Build.Tasks.Csc,位于 MSBuildTasks.dll 程序集中(请在同一目录下 确认这一 .dll文件的存在)。这样,MSBuild引擎在遇到对Csc任务的调用时就会 通过这里的注册信息来确定 Csc所在的程序集,从而最
40、终运行相应的托管代码。 这样,如果你自己也写了不同的 Task,请按同样的方式对它进行注册以便使用。 如果你引用了一个还没有注册的 Target,那么MSBuild引擎将无法找到它的存在 而导致生成失败。当然,MSBuild Task的注册方式不止以上一种。以上注册方法的影响范围是 全局,你可以在每一个 Project里应用上面注册的那些 Task。但你也可以选择在 Project范围内注册Task,这将对应着另外一种略有不同的方法。我会在后面的 一篇文章里给出具体介绍。在这里,你只需明白你所需要的Task在哪里找到,而它们的具体用法可以通过参考 MSBuildTasks 文来获得,在这里我就不细说 了。2.3 MSBuild 运行OK,介绍了一长串,还是快点把我们的Build.csproj运行起来吧。请在shell 的同一目录下输入以下命令:MSBuild或者:MSBuild Build.cs proj运行结果如下:d:DevMyMSBuildDemo>msbuild Build.cs projmsbuild Build.cs projMicrosoft (
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 退化防护林修复技术规定
- 食品企业刀具与碎片管理程序
- 项目投标情况交底清单
- 肠息肉切除术后并发症处理
- 辽宁省阜新市2026年高三第四次模拟考试语文试卷含解析
- 医学26年:呼吸系统疾病营养支持 查房课件
- 四川省遂宁市射洪中学2025-2026学年高二下学期期中考试数学试卷
- 26年银发法律维权难解决方案课件
- 医学26年:肉毒素治疗偏头痛 查房课件
- 医学26年:糖尿病酮症酸中毒处理 查房课件
- 2026年江苏南京市高三二模高考物理试卷试题(含答案详解)
- 第13课 每个人都有梦想 课件(内嵌视频)2025-2026学年道德与法治二年级下册统编版
- 2026四川省成都广定发展集团有限公司招聘3人备考题库(含答案详解)
- 2026四川成都市公共交通集团有限公司招聘投资管理专员岗位备考题库附答案详解(b卷)
- 【完整版】施工现场群体性事件应急预案
- 2026年普通高等学校招生全国统一考试语文模拟预测卷(附答案)(2026高考语文终极押卷)
- (完整版)旅游学概论期末试题(附答案)
- 2025年广东省深圳市初二学业水平地理生物会考真题试卷(+答案)
- 2026首创证券股份有限公司校园招聘备考题库附答案详解ab卷
- 2026年演出经纪人资格证考前冲刺模拟题库附答案详解【培优B卷】
- 房屋市政工程生产安全重大事故隐患检查专用表
评论
0/150
提交评论