一、前言
MSBuild是一个既熟悉又陌生的名字,Visual Studio的项目加载和构建均通过MSBuild来实现。VS中右键打开项目菜单,对应MSBuild的Build目标,对应MSBuild的Rebuild目标,对应MSBuild的Clean目标,对应MSBuild的PublishOnly目标。到这里我想大家都明白MSBuild就和Ant一样就是一个用于项目构建的任务执行引擎,只不过它被融入到VS中,降低了入门难度。但融入VS中只是方便我们使用而已,并不代表不用了解学习,尤其项目规模愈发庞大时,编写结构良好的MSBuild Script来作为项目构建和管理的基石是必不可少。
本文是近日的学习记录,学习目标是看懂*.csproj项目文件的信息。若有纰漏请大家指正,谢谢。
附件知识 :
*.sln : 项目、解决方案在磁盘上的引用,VS通过该类文件加载整个项目、解决方案;
*.suo : 保存VS用户界面的自定义配置(包括布局、断电和项目最后编译后而又没有关闭的文件标签等),下一次打开VS时会恢复这些配置;
*.csproj.user: 保存VS的个人配置;
*.csproj : XML格式,保存项目的依赖项和项目构建步骤、任务等。(需要上传到版本库的)
注意:以下内容均以.NET Framework 4.0为环境。
目录一大坨:
二、MSBuild的组成
三、从实例学MSBuild Script
1. Project元素
2. ItemGroup/Item元素
3. PropertyGroup/Property元素
4. Task元素
5. UsingTask元素
6. Target元素
7. Choose元素
8. Import元素
9. ProjectExtensions元素
四、特殊字符
五、Condition的属性形式
六、通配符
七、生成解决方案中的特定目标
八、小结
九、参考
二、MSBuild的组成
MSBuild由两部分组成:脚本 和 执行引擎。
脚本:就是带变量、函数、流程控制的可编程语言。MSBuild Script是基于XML schema的,和Ant、Maven等差不多。
执行引擎:以脚本、变量、环境变量作为输入,对脚本进行解析执行。
三、从实例学MSBuild Script
直接到MSDN学习是一个不错的选择,但为了降低学习难度我们以**.csproj项目文件作为切入点。
在VS2013下新建名为LearnMSBuild的MVC4项目,然后在项目目录下有LearnMSBuild.csproj和LearnMSBuild.csproj.user两个项目文件,而里面就是MSBuild Script了。
在VS中查看LearnMSBuild.csproj的方法:右键点击项目->卸载项目->右键点击项目->编辑LearnMSBuild.csproj。
"1.0" encoding="utf-8"?>"12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> "$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> " '$(Configuration)' == '' ">Debug " '$(Platform)' == '' ">AnyCPU 2.0 {13508D65-AC7D-4462-9106-2E8EC81F677D} {E3E379DF-F4C6-4180-9B81-6769533ABE47};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} Library Properties MvcApplication1 MvcApplication1 v4.0 false true " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> true full false bin\ DEBUG;TRACE prompt 4 " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> pdbonly true bin\ TRACE prompt 4 "Microsoft.CSharp" /> "System" /> "System.Data" /> "System.Data.Entity" /> "System.Drawing" /> "System.Web.DynamicData" /> "System.Web.Entity" /> "System.Web.ApplicationServices" /> "System.ComponentModel.DataAnnotations" /> "System.Core" /> "System.Data.DataSetExtensions" /> "System.Xml.Linq" /> "System.Web" /> "System.Web.Extensions" /> "System.Web.Abstractions" /> "System.Web.Routing" /> "System.Xml" /> "System.Configuration" /> "System.Web.Services" /> "System.EnterpriseServices" /> "EntityFramework"> ..\packages\EntityFramework.5.0.0\lib\net40\EntityFramework.dll "Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> True ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll "Microsoft.Web.Mvc.FixedDisplayModes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> True ..\packages\Microsoft.AspNet.Mvc.FixedDisplayModes.1.0.0\lib\net40\Microsoft.Web.Mvc.FixedDisplayModes.dll "Newtonsoft.Json"> ..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll "System.Net.Http"> True ..\packages\Microsoft.Net.Http.2.0.30506.0\lib\net40\System.Net.Http.dll "System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> ..\packages\Microsoft.AspNet.WebApi.Client.4.0.30506.0\lib\net40\System.Net.Http.Formatting.dll "System.Net.Http.WebRequest"> True ..\packages\Microsoft.Net.Http.2.0.30506.0\lib\net40\System.Net.Http.WebRequest.dll "System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> ..\packages\Microsoft.AspNet.WebApi.Core.4.0.30506.0\lib\net40\System.Web.Http.dll "System.Web.Http.WebHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll "System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> True ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll "System.Web.Optimization"> ..\packages\Microsoft.AspNet.Web.Optimization.1.0.0\lib\net40\System.Web.Optimization.dll "System.Web.Providers"> ..\packages\Microsoft.AspNet.Providers.Core.1.2\lib\net40\System.Web.Providers.dll "System.Web.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> True ..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll "System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> True ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.dll "System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> True ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Deployment.dll "System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> True ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll "WebGrease"> True ..\packages\WebGrease.1.3.0\lib\WebGrease.dll "Antlr3.Runtime"> True ..\packages\WebGrease.1.3.0\lib\Antlr3.Runtime.dll "App_Start\BundleConfig.cs" /> "App_Start\FilterConfig.cs" /> "App_Start\RouteConfig.cs" /> "App_Start\WebApiConfig.cs" /> "Global.asax.cs"> Global.asax "Properties\AssemblyInfo.cs" /> "Content\themes\base\images\ui-bg_flat_0_aaaaaa_40x100.png" /> "Content\themes\base\images\ui-bg_flat_75_ffffff_40x100.png" /> "Content\themes\base\images\ui-bg_glass_55_fbf9ee_1x400.png" /> "Content\themes\base\images\ui-bg_glass_65_ffffff_1x400.png" /> "Content\themes\base\images\ui-bg_glass_75_dadada_1x400.png" /> "Content\themes\base\images\ui-bg_glass_75_e6e6e6_1x400.png" /> "Content\themes\base\images\ui-bg_glass_95_fef1ec_1x400.png" /> "Content\themes\base\images\ui-bg_highlight-soft_75_cccccc_1x100.png" /> "Content\themes\base\images\ui-icons_222222_256x240.png" /> "Content\themes\base\images\ui-icons_2e83ff_256x240.png" /> "Content\themes\base\images\ui-icons_454545_256x240.png" /> "Content\themes\base\images\ui-icons_888888_256x240.png" /> "Content\themes\base\images\ui-icons_cd0a0a_256x240.png" /> "Content\themes\base\jquery-ui.css" /> "Content\themes\base\jquery.ui.accordion.css" /> "Content\themes\base\jquery.ui.all.css" /> "Content\themes\base\jquery.ui.autocomplete.css" /> "Content\themes\base\jquery.ui.base.css" /> "Content\themes\base\jquery.ui.button.css" /> "Content\themes\base\jquery.ui.core.css" /> "Content\themes\base\jquery.ui.datepicker.css" /> "Content\themes\base\jquery.ui.dialog.css" /> "Content\themes\base\jquery.ui.progressbar.css" /> "Content\themes\base\jquery.ui.resizable.css" /> "Content\themes\base\jquery.ui.selectable.css" /> "Content\themes\base\jquery.ui.slider.css" /> "Content\themes\base\jquery.ui.tabs.css" /> "Content\themes\base\jquery.ui.theme.css" /> "Content\themes\base\minified\images\ui-bg_flat_0_aaaaaa_40x100.png" /> "Content\themes\base\minified\images\ui-bg_flat_75_ffffff_40x100.png" /> "Content\themes\base\minified\images\ui-bg_glass_55_fbf9ee_1x400.png" /> "Content\themes\base\minified\images\ui-bg_glass_65_ffffff_1x400.png" /> "Content\themes\base\minified\images\ui-bg_glass_75_dadada_1x400.png" /> "Content\themes\base\minified\images\ui-bg_glass_75_e6e6e6_1x400.png" /> "Content\themes\base\minified\images\ui-bg_glass_95_fef1ec_1x400.png" /> "Content\themes\base\minified\images\ui-bg_highlight-soft_75_cccccc_1x100.png" /> "Content\themes\base\minified\images\ui-icons_222222_256x240.png" /> "Content\themes\base\minified\images\ui-icons_2e83ff_256x240.png" /> "Content\themes\base\minified\images\ui-icons_454545_256x240.png" /> "Content\themes\base\minified\images\ui-icons_888888_256x240.png" /> "Content\themes\base\minified\images\ui-icons_cd0a0a_256x240.png" /> "Content\themes\base\minified\jquery-ui.min.css" /> "Content\themes\base\minified\jquery.ui.accordion.min.css" /> "Content\themes\base\minified\jquery.ui.autocomplete.min.css" /> "Content\themes\base\minified\jquery.ui.button.min.css" /> "Content\themes\base\minified\jquery.ui.core.min.css" /> "Content\themes\base\minified\jquery.ui.datepicker.min.css" /> "Content\themes\base\minified\jquery.ui.dialog.min.css" /> "Content\themes\base\minified\jquery.ui.progressbar.min.css" /> "Content\themes\base\minified\jquery.ui.resizable.min.css" /> "Content\themes\base\minified\jquery.ui.selectable.min.css" /> "Content\themes\base\minified\jquery.ui.slider.min.css" /> "Content\themes\base\minified\jquery.ui.tabs.min.css" /> "Content\themes\base\minified\jquery.ui.theme.min.css" /> "Global.asax" /> "Content\Site.css" /> "Scripts\jquery-1.8.2.intellisense.js" /> "Scripts\jquery-1.8.2.js" /> "Scripts\jquery-1.8.2.min.js" /> "Scripts\jquery.validate-vsdoc.js" /> "Scripts\jquery-ui-1.8.24.js" /> "Scripts\jquery-ui-1.8.24.min.js" /> "Scripts\jquery.unobtrusive-ajax.js" /> "Scripts\jquery.unobtrusive-ajax.min.js" /> "Scripts\jquery.validate.js" /> "Scripts\jquery.validate.min.js" /> "Scripts\jquery.validate.unobtrusive.js" /> "Scripts\jquery.validate.unobtrusive.min.js" /> "Scripts\knockout-2.2.0.debug.js" /> "Scripts\knockout-2.2.0.js" /> "Scripts\modernizr-2.6.2.js" /> "Scripts\_references.js" /> "Web.config" /> "Web.Debug.config"> Web.config "Web.Release.config"> Web.config "Views\Web.config" /> "Views\_ViewStart.cshtml" /> "Views\Shared\Error.cshtml" /> "Views\Shared\_Layout.cshtml" /> "App_Data\" /> "Controllers\" /> "Models\" /> "packages.config" /> "'$(VisualStudioVersion)' == ''">10.0 "'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) "$(MSBuildBinPath)\Microsoft.CSharp.targets" /> "$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> "$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" /> "MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'"> "temp" PhysicalPath="$(WebProjectOutputDir)" /> "{349c5851-65df-11da-9384-00065b846f21}"> True True 40646 / http://localhost:40646/ False False False "test.txt"> tst/ "test1.txt"> tst/ "HW" Inputs="@(F)" Outputs="@(F->'%(OP)%(Filename)%(Extension)')"> "%(F.OP)"/> "@(F)" DestinationFolder="%(F.OP)" />
1. Project元素
作用:根节点,用于配置项目级信息。
属性名 | 说明 |
ToolsVersion | 指定执行引擎的版本号 |
InitialTargets | 指定初始化时执行的目标组,多个目标间通过分号(;)分隔 |
DefaultTargets | 指定默认执行的目标组,多个目标间通过分号(;)分隔 |
2. ItemGroup/Item元素
ItemGroup 用于对N个Item元素进行分类整理,并可通过Condition属性对旗下的Item元素进行是否生效的统一控制。
Item
作用:对一个或多个文件的命名引用。可包含元数据(如文件名、路径和版本号),元数据均以子元素的形式定义。
属性名 | 说明 |
Include | 指定引入的文件绝对/相对路径 或 程序集名,多个值间通过分号(;)分隔 |
Exclude | 指定不引入的文件绝对/相对路径 或 程序集名,多个值间通过分号(;)分隔 |
Condition | 判断是否生效 |
获取Item的Include值: @(ItemType, Separator) ,Separator默认是分号(;) |
Item的子元素作为其元数据。获取元数据: %(ItemType.ItemMetadata)
示例——定义名为Script的Item
"Nothing"> // 执行结果:Script/jquery.js;Script/app.js+01"@(Script)+%(Script.Version)" />
MSBuild执行引擎中内置部分预定义的Item,具体如下:
Item名 | 元数据名 | 元数据说明 |
Reference (设置程序集(托管)引用) | HintPath | 程序集的绝对或相对路径 |
Name | 程序集的显示名称 | |
FusionName | 程序集的强签名名称 | |
SpecificVersion | true表示程序集版本号必须与FunsionName指定的一致;false表示不必一致 | |
Aliases | 程序集的别名 | |
Private | 用于决定是否将程序集赋值到输出目录中。Never/Always(默认值)/PreserveNewest | |
Compile (编译器的源文件) | DependentUpon | 指出文件正确编译所依赖的文件 |
AutoGen | true表示由VS为项目生成的文件 | |
Link | 文件在物理上处于项目文件的影响范围之外时要显示的符号路径 | |
Visible | true表示在 Visual Studio 中的“解决方案资源管理器”中显示文件 | |
CopyToOutputDirectory | 确定是否将文件复制到输出目录。Never/Always(默认值)/PreserveNewest | |
Content (表示不会编译到项目中,但可能会嵌入其中或随其一起发布的文件) | DependentUpon | 依赖文件 |
Generator | 文件生成器的名称 | |
LastGenOutput | 文件生成器创建的文件的名称 | |
CustomToolNamespace | 文件生成器应在其中创建代码的命名空间 | |
Link | true表示在VS中的解决方案资源管理器中显示文件 | |
PublishState | 内容的发布状态.Default/Included/Excluded/DataFile/必备组件 | |
IsAssembly | true表示是文件时程序集 | |
Visible | true表示在VS中的解决方案资源管理器中显示文件 | |
CopyToOutputDirectory | 确定是否将文件复制到输出目录。Never/Always(默认值)/Pre | |
None(表示不应在生成过程中具有角色的文件,但同样可输出到生成目录中(默认是不输出到生成目录和不发布)) | DependentUpon | 依赖文件 |
Generator | 文件生成器的名称 | |
LastGenOutput | 文件生成器创建的文件的名称 | |
CustomToolNamespace | 文件生成器应在其中创建代码的命名空间 | |
Link | 文件在物理上处于项目的影响范围之外时要显示的符号路径 | |
Visible | true表示在VS中的解决方案资源管理器中显示文件 | |
CopyToOutputDirectory | 确定是否将文件复制到输出目录。Never/Always(默认值)/PreserveNewest | |
COMReference (COM(非托管)组件引用) | ||
COMFileReference (馈送到ResolvedComreference目标中的类型库的列表) |
||
NativeReference (本机清单文件或对此类文件的引用) | ||
ProjectReference (对另一个.proj文件的引用) | ||
BaseApplicationManifest (表示用于生成的基本应用程序清单,包含ClickOnce部署安全信息) | ||
CodeAnalysisImport (表示要导入的FxCop项目) | ||
EmbeddedResource(要在生成的程序集中嵌入的资源) | ||
Import (表示应由Visual Basic编译器导入其命名空间的程序集) |
MSBuild执行引擎中为每个Item预设的元数据,具体如下:
元数据名 | 元数据说明 |
FullPath | 当前项所指向的文件的绝对路径 |
RootDir | 当前项所指向的文件的根目录 |
Filename | 当前项所指向的文件的不含扩展名的名称 |
Extension | 当前项所指向的文件的扩展名 |
RelativeDir | 当前项所指向的文件的相对路径(以\为结尾) |
Directory | 当前项所指向的文件的目录(以\为结尾) |
RecursiveDir | 当项的Include中包含**,则存放**匹配到的目录路径 |
Identity | %(RelativeDir)\%(Filename)%(Extension) |
ModifiedTime | 最后修改时间 |
CreatedTime | 创建时间 |
AccessedTime | 最后访问时间 |
示例:
"HelloWorld.cs"> "Test"> "%(MyItem.FileName)"/> Target // 输出 HelloWorld
*元数据转换(MSBuild Transform)*
增量生成就会用到MSBuild Transform。
作用:将一组Item转换为一组输出值
语法: @(ItemType->'%(metadata)')
"CopyOutputs" Inputs="@(BuiltAssemblies)" Outputs="@(BuiltAssemblies -> '$(OutputPath)%(Filename)%(Extension)')"> <Copy SourceFiles="@(BuiltAssemblies)" DestinationFolder="$(OutputPath)"/> 假定BuiltAssemblies如下"a.txt"> "b.txt"> "c.txt"> Inputs="@(BuiltAssemblies)" Outputs="@(BuiltAssemblies -> '$(OutputPath)%(Filename)%(Extension)')" 会建立以下的mapping a.txt(时间戳) <-> bin\a.txt(时间戳) b.txt(时间戳) <-> bin\b.txt(时间戳) c.txt(时间戳) <-> bin\c.txt(时间戳) 在执行Target时,会根据Mapping来检查两者的时间戳,若Output的没有时间戳或小于Input的时间戳则该Input项会列入执行的范围,否则则不再被解析执行。
3. PropertyGroup/Property元素
PropertyGroup:属性组,用于整理归类Property
Property:配置信息的键值对
项 | 明细 | 示例 |
定义属性 | <属性名>属性值属性名> | |
调用 | $(属性名) | |
注意 | 在启动执行引擎时,可从通过/property选项设置,并在脚本中通过$(属性名)的方式来引用 | shell> MSBuild /property:buildMode=release 脚本文件路径 |
在启动执行引擎时,可从脚本中通过$(属性名)的方式来引用 | ||
在启动执行引擎时,MSBuild预留一些保留属性,供脚本引用 | $(MSBuildProjectDirectory) 项目所在的目录 | |
$(MSBuildProjectFileName) 项目文件的含扩展名的文件名 | ||
$(MSBuildProjectExtension) 项目文件的扩展名 | ||
$(MSBuildProjectFullPath) 项目文件的完整路径 | ||
$(MSBuildProjectName) 不带扩展名的项目文件的文件名 | ||
$(MSBuildBinPath) MSBuild所在的目录 |
4. Task元素
执行具体任务的任务执行程序。
属性:
属性名 | 说明 | ||
Condition | 生效条件 | ||
ContinueOnError | .NET Framework4.5前只支持true和false |
WarnAndContinue | 当任务失败时,报警告,当会继续执行 |
true | 当任务失败时,报警告,当会继续执行 | ||
ErrorAndContinue | 当任务失败时,报错误,当会继续执行 | ||
ErrorAndStop | 当任务失败时,包错误,且不会继续执行 | ||
false | 当任务失败时,包错误,且不会继续执行 | ||
Parameter | 实参,如 Name="fsjohnhuang" |
子元素:
子元素 | 属性名 | 说明 |
Output | TaskParameter | 输出参数的名称 |
PropertyName | 接收任务输出参数值的属性,后续可通过$(PropertyName)来引用该属性。PropertyName和ItemName存在互斥关系 | |
ItemName | 接收任务输出参数值的项,后续可通过@(ItemName)来引用该项。PropertyName和ItemName存在互斥关系 | |
Condition | 生效条件 |
"Compile" DependsOnTargets="Resources"> "@(CSFile)" TargetType="library" Resources="@(CompiledResources)" EmitDebugInformation="$(includeDebugInformation)" References="@(Reference)" DebugType="$(debuggingType)" OutputAssembly="$(builtdir)\$(MSBuildProjectName).dll" >
分类:
分类 | 说明 | 示例 |
MSBuild内置任务执行程序 | 由MSBuild预定义的任务执行程序,如Csc、Message等 | |
外部任务执行程序 | 通过MSBuild内置任务执行程序Exec来调用操作系统内的任意程序来执行任务 | |
自定义任务执行程序 | 继承ITask接口 1. 若要覆盖MSBuild内置任务执行程序则将程序集保存在.NET Framework的目录下,并且后缀必须为.OverrideTasks或.Tasks; 2. 若不覆盖,则通过UsingTask元素的AssemblyFile或AssemblyName属性引入。 |
|
通过UsingTask来定义内联任务(.NET Framework 4 的特性) |
5. UsingTask元素
作用:定义和引入任务执行程序
属性:
属性名 | 说明 | 注意 |
AssemblyName | 要加载的程序集的名称,设置后不能设置AssemblyFile | 任务的实现类,必须继承ITask接口 |
AssemblyFile | 要加载的程序集的路径,设置后不能设置AssemblyName | 任务的实现类,必须继承ITask接口 |
TaskFactory | 指定用于创建Task实例的工厂类 | |
TaskName | 任务名称 | |
Condition | 生效条件 |
子元素:
元素 | 元素属性/子元素 | 属性/子元素说明 | 元素属性/子元素 | 属性/子元素说明 | 示例 |
ParameterGroup 包含参数列表 | Parameter元素 | 参数 | ParameterType | 参数类型 |
|
Required | true:必要参数 | ||||
Output | 和C#的out一样 | ||||
TaskBody | Evaludate | true: 表示TaskBody子元素将被计算并运用到TaskFactory中 | |||
Task (用于定义内联任务) |
定义内联任务——Task元素详解
1. 直接在项目文件中编写任务,而不必引用外部包含继承ITask接口的类的程序集
2. 可用支持.NET CodeDom 语言(例如,Visual Basic、Visual C# 或 JScript)来编写任务逻辑
子元素:
元素 | 属性/子元素 | 属性/子元素说明 |
Reference (如同在VS中通过引入程序集一样) | ||
Using (如同C# 的Using) | ||
Code (编写代码) | Type | 代码类型,值如下: Class (Code元素包含派生自ITask接口的类代码) Method (Code元素包含定义ITask接口的Execute方法的重写(方法签名+方法体)) Fragment (Code元素中仅包含Execute方法的方法体代码) |
Language | 编码的语言,值如下: cs (C#) VB(vbs) |
|
Source | 指定存储Code子元素的文件路径 1. 设置Source后,Type默认为Class 2. 不设置Source,Type默认为Fragment |
|
子元素 | 任务实现的代码 |
注意:当UsingTask中出现子元素Task时,则UsingTask的属性TaskFactory必须为CodeTaskFactory,AssemblyFile为$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll。
"12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> "Nothing" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll"> "Fragment" Language="cs"> "System.Core"/> "System" /> "System.IO" /> "System.Net" /> "Microsoft.Build.Framework" /> "Microsoft.Build.Utilities" /> "Fragment" Language="cs"> [CDATA[ try { OutputFilename = Path.GetFullPath(OutputFilename); Log.LogMessage("Downloading latest version of NuGet.exe..."); WebClient webClient = new WebClient(); webClient.DownloadFile("https://www.nuget.org/nuget.exe", OutputFilename); return true; } catch (Exception ex) { Log.LogErrorFromException(ex); return false; } ]]>
6. Target元素
作用:针对某项工作,有序地组织多个Task。是对外的最小执行单位
属性:
属性名 | 说明 |
Name | 目标名称 |
DependsOnTargets | 在执行该目标前,先执行指定的目标。多个目标时,通过分号(;)分隔 |
Condition | 生效条件 |
Inputs | 指定存储目标输入的文件路径,多个文件路径间通过分号(;)分隔 |
Outputs | 指定存储目标输出的文件路径,多个文件路径间通过分号(;)分隔 |
BeforeTargets | 执行指定的目标(多个目标间通过分号分隔)前,先要执行当前目标 |
AfterTargets | 执行指定的目标(多个目标间通过分号分隔)后,要执行当前目标 |
Label | 标识 |
KeepDuplicateOutputs | true:Outputs中含有多个重复的Reference不会被排重。默认为false |
Returns | 目标的一组返回项,返回给调用该目标的任务。若没有设置该项,则会返回Outputs的内容 |
子元素:
元素 | 属性 | 属性说明 |
OnError (存在多个OnError元素时,目标失败后会按顺序依次执行) | ExecuteTargets | 指定任务失败时执行的目标(多个目标间通过分号分隔) |
Condition | 生效条件 |
注意:1.一次生成过程仅会执行同一个Target一次,当出现重复调用时会忽略,且返回第一次调用后的返回值;
2.Target重复定义时,采取最后定义有效的原则
7. Choose元素
作用:根据条件使部分Property/PropertyGroup/ItemGroup生效
子元素:
元素 | 说明 |
When | |
Otherwise |
8. Import元素
作用:将另一个项目文件导入到当前的项目文件
属性:
属性名 | 说明 |
Project 项目文件的绝对或相对路径 | 1. 相对路径,是相对于当前项目文件的路径而言; 2. 可使用通配符(*,**和?) |
Condition | 生效条件 |
注意:1. 若当前项目文件没有DefaultTargets属性,则会按引入顺序寻找各被导入的项目文件的DefaultTargets属性,并执行第一个搜索到的DefaultTargets属性值;
2. 共享的导入项目文件的命名规范是以.targets作为扩展名(如:.nuget/NuGet.targets)
ImportGroup元素用于组织整理Import元素。
9. ProjectExtensions元素
作用:内部包含的内容,将不被MSBuild解析执行
四、特殊字符
特殊字符:在MSBuild Script有特殊含义和用途的字符,若将它们作为普通字符输出时,需要通过%xx,xx为字符的ASCII的十六进制值的字面量来表示。
特殊字符 | %xx字面量 |
* | %2A |
% | %25 |
@ | %40 |
' | %27 |
? | %3F |
$ | %24 |
; | %3B |
五、Condition属性的形式
断言/作用 | 语法 |
等于 | 'stringA' == 'stringB' |
不等于 | 'stringA' != 'stringB' |
小于、大于、小于等于和大于等于 | <,>,<=,>= |
存在 | Exists('stringA') |
以正斜线为结尾 | HasTrailingSlash('stringA') |
非 | ! |
逻辑与 | And |
逻辑或 | Or |
提高优先级 | () |
六、通配符
假定目录结构为
workspace
|-------- i.gif
| test.gif
|-------- cd
|------- c.gif
通配符 | 说明 | 示例 |
* | 配置任意数量的任意字符,仅限于文件级别 | 1. *.gif匹配出 i.gif和test.gif 2. t*.gif匹配出 test.gif |
** | 配置无限制的目录级别 | 1. **匹配出 i.gif、test.gif和cd/c.gif 2. **/*.gif匹配出 cd/c.gif |
? | 配置一个任意字符 | ?.gif匹配出 i.gif |
七、生成解决方案中的特定目标
MSBuild.exe
八、小结
本文主要是针对**.csproj中出现的元素来学习MSBuild Script,日后理论*实践后继续补充。
尊重原创,转载请注明来自:^_^肥子John http://www.cnblogs.com/fsjohnhuang/p/4490562.html
九、参考
https://msdn.microsoft.com/zh-cn/library/dd637714.aspx