.NET魔法堂:工程构建基石->MSBuild

简介:

一、前言                            

  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。

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>
    </ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{13508D65-AC7D-4462-9106-2E8EC81F677D}</ProjectGuid>
    <ProjectTypeGuids>{E3E379DF-F4C6-4180-9B81-6769533ABE47};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>MvcApplication1</RootNamespace>
    <AssemblyName>MvcApplication1</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <MvcBuildViews>false</MvcBuildViews>
    <UseIISExpress>true</UseIISExpress>
    <IISExpressSSLPort />
    <IISExpressAnonymousAuthentication />
    <IISExpressWindowsAuthentication />
    <IISExpressUseClassicPipelineMode />
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Data.Entity" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Web.DynamicData" />
    <Reference Include="System.Web.Entity" />
    <Reference Include="System.Web.ApplicationServices" />
    <Reference Include="System.ComponentModel.DataAnnotations" />
    <Reference Include="System.Core" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Web" />
    <Reference Include="System.Web.Extensions" />
    <Reference Include="System.Web.Abstractions" />
    <Reference Include="System.Web.Routing" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Configuration" />
    <Reference Include="System.Web.Services" />
    <Reference Include="System.EnterpriseServices" />
    <Reference Include="EntityFramework">
      <HintPath>..\packages\EntityFramework.5.0.0\lib\net40\EntityFramework.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <Private>True</Private>
      <HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Web.Mvc.FixedDisplayModes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <Private>True</Private>
      <HintPath>..\packages\Microsoft.AspNet.Mvc.FixedDisplayModes.1.0.0\lib\net40\Microsoft.Web.Mvc.FixedDisplayModes.dll</HintPath>
    </Reference>
    <Reference Include="Newtonsoft.Json">
      <HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
    </Reference>
    <Reference Include="System.Net.Http">
      <Private>True</Private>
      <HintPath>..\packages\Microsoft.Net.Http.2.0.30506.0\lib\net40\System.Net.Http.dll</HintPath>
    </Reference>
    <Reference Include="System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.AspNet.WebApi.Client.4.0.30506.0\lib\net40\System.Net.Http.Formatting.dll</HintPath>
    </Reference>
    <Reference Include="System.Net.Http.WebRequest">
      <Private>True</Private>
      <HintPath>..\packages\Microsoft.Net.Http.2.0.30506.0\lib\net40\System.Net.Http.WebRequest.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.AspNet.WebApi.Core.4.0.30506.0\lib\net40\System.Web.Http.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.Http.WebHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <Private>True</Private>
      <HintPath>..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.Optimization">
      <HintPath>..\packages\Microsoft.AspNet.Web.Optimization.1.0.0\lib\net40\System.Web.Optimization.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.Providers">
      <HintPath>..\packages\Microsoft.AspNet.Providers.Core.1.2\lib\net40\System.Web.Providers.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <Private>True</Private>
      <HintPath>..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <Private>True</Private>
      <HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <Private>True</Private>
      <HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Deployment.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <Private>True</Private>
      <HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll</HintPath>
    </Reference>
    <Reference Include="WebGrease">
      <Private>True</Private>
      <HintPath>..\packages\WebGrease.1.3.0\lib\WebGrease.dll</HintPath>
    </Reference>
    <Reference Include="Antlr3.Runtime">
      <Private>True</Private>
      <HintPath>..\packages\WebGrease.1.3.0\lib\Antlr3.Runtime.dll</HintPath>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="App_Start\BundleConfig.cs" />
    <Compile Include="App_Start\FilterConfig.cs" />
    <Compile Include="App_Start\RouteConfig.cs" />
    <Compile Include="App_Start\WebApiConfig.cs" />
    <Compile Include="Global.asax.cs">
      <DependentUpon>Global.asax</DependentUpon>
    </Compile>
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="Content\themes\base\images\ui-bg_flat_0_aaaaaa_40x100.png" />
    <Content Include="Content\themes\base\images\ui-bg_flat_75_ffffff_40x100.png" />
    <Content Include="Content\themes\base\images\ui-bg_glass_55_fbf9ee_1x400.png" />
    <Content Include="Content\themes\base\images\ui-bg_glass_65_ffffff_1x400.png" />
    <Content Include="Content\themes\base\images\ui-bg_glass_75_dadada_1x400.png" />
    <Content Include="Content\themes\base\images\ui-bg_glass_75_e6e6e6_1x400.png" />
    <Content Include="Content\themes\base\images\ui-bg_glass_95_fef1ec_1x400.png" />
    <Content Include="Content\themes\base\images\ui-bg_highlight-soft_75_cccccc_1x100.png" />
    <Content Include="Content\themes\base\images\ui-icons_222222_256x240.png" />
    <Content Include="Content\themes\base\images\ui-icons_2e83ff_256x240.png" />
    <Content Include="Content\themes\base\images\ui-icons_454545_256x240.png" />
    <Content Include="Content\themes\base\images\ui-icons_888888_256x240.png" />
    <Content Include="Content\themes\base\images\ui-icons_cd0a0a_256x240.png" />
    <Content Include="Content\themes\base\jquery-ui.css" />
    <Content Include="Content\themes\base\jquery.ui.accordion.css" />
    <Content Include="Content\themes\base\jquery.ui.all.css" />
    <Content Include="Content\themes\base\jquery.ui.autocomplete.css" />
    <Content Include="Content\themes\base\jquery.ui.base.css" />
    <Content Include="Content\themes\base\jquery.ui.button.css" />
    <Content Include="Content\themes\base\jquery.ui.core.css" />
    <Content Include="Content\themes\base\jquery.ui.datepicker.css" />
    <Content Include="Content\themes\base\jquery.ui.dialog.css" />
    <Content Include="Content\themes\base\jquery.ui.progressbar.css" />
    <Content Include="Content\themes\base\jquery.ui.resizable.css" />
    <Content Include="Content\themes\base\jquery.ui.selectable.css" />
    <Content Include="Content\themes\base\jquery.ui.slider.css" />
    <Content Include="Content\themes\base\jquery.ui.tabs.css" />
    <Content Include="Content\themes\base\jquery.ui.theme.css" />
    <Content Include="Content\themes\base\minified\images\ui-bg_flat_0_aaaaaa_40x100.png" />
    <Content Include="Content\themes\base\minified\images\ui-bg_flat_75_ffffff_40x100.png" />
    <Content Include="Content\themes\base\minified\images\ui-bg_glass_55_fbf9ee_1x400.png" />
    <Content Include="Content\themes\base\minified\images\ui-bg_glass_65_ffffff_1x400.png" />
    <Content Include="Content\themes\base\minified\images\ui-bg_glass_75_dadada_1x400.png" />
    <Content Include="Content\themes\base\minified\images\ui-bg_glass_75_e6e6e6_1x400.png" />
    <Content Include="Content\themes\base\minified\images\ui-bg_glass_95_fef1ec_1x400.png" />
    <Content Include="Content\themes\base\minified\images\ui-bg_highlight-soft_75_cccccc_1x100.png" />
    <Content Include="Content\themes\base\minified\images\ui-icons_222222_256x240.png" />
    <Content Include="Content\themes\base\minified\images\ui-icons_2e83ff_256x240.png" />
    <Content Include="Content\themes\base\minified\images\ui-icons_454545_256x240.png" />
    <Content Include="Content\themes\base\minified\images\ui-icons_888888_256x240.png" />
    <Content Include="Content\themes\base\minified\images\ui-icons_cd0a0a_256x240.png" />
    <Content Include="Content\themes\base\minified\jquery-ui.min.css" />
    <Content Include="Content\themes\base\minified\jquery.ui.accordion.min.css" />
    <Content Include="Content\themes\base\minified\jquery.ui.autocomplete.min.css" />
    <Content Include="Content\themes\base\minified\jquery.ui.button.min.css" />
    <Content Include="Content\themes\base\minified\jquery.ui.core.min.css" />
    <Content Include="Content\themes\base\minified\jquery.ui.datepicker.min.css" />
    <Content Include="Content\themes\base\minified\jquery.ui.dialog.min.css" />
    <Content Include="Content\themes\base\minified\jquery.ui.progressbar.min.css" />
    <Content Include="Content\themes\base\minified\jquery.ui.resizable.min.css" />
    <Content Include="Content\themes\base\minified\jquery.ui.selectable.min.css" />
    <Content Include="Content\themes\base\minified\jquery.ui.slider.min.css" />
    <Content Include="Content\themes\base\minified\jquery.ui.tabs.min.css" />
    <Content Include="Content\themes\base\minified\jquery.ui.theme.min.css" />
    <Content Include="Global.asax" />
    <Content Include="Content\Site.css" />
    <None Include="Scripts\jquery-1.8.2.intellisense.js" />
    <Content Include="Scripts\jquery-1.8.2.js" />
    <Content Include="Scripts\jquery-1.8.2.min.js" />
    <None Include="Scripts\jquery.validate-vsdoc.js" />
    <Content Include="Scripts\jquery-ui-1.8.24.js" />
    <Content Include="Scripts\jquery-ui-1.8.24.min.js" />
    <Content Include="Scripts\jquery.unobtrusive-ajax.js" />
    <Content Include="Scripts\jquery.unobtrusive-ajax.min.js" />
    <Content Include="Scripts\jquery.validate.js" />
    <Content Include="Scripts\jquery.validate.min.js" />
    <Content Include="Scripts\jquery.validate.unobtrusive.js" />
    <Content Include="Scripts\jquery.validate.unobtrusive.min.js" />
    <Content Include="Scripts\knockout-2.2.0.debug.js" />
    <Content Include="Scripts\knockout-2.2.0.js" />
    <Content Include="Scripts\modernizr-2.6.2.js" />
    <Content Include="Scripts\_references.js" />
    <Content Include="Web.config" />
    <Content Include="Web.Debug.config">
      <DependentUpon>Web.config</DependentUpon>
    </Content>
    <Content Include="Web.Release.config">
      <DependentUpon>Web.config</DependentUpon>
    </Content>
    <Content Include="Views\Web.config" />
    <Content Include="Views\_ViewStart.cshtml" />
    <Content Include="Views\Shared\Error.cshtml" />
    <Content Include="Views\Shared\_Layout.cshtml" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="App_Data\" />
    <Folder Include="Controllers\" />
    <Folder Include="Models\" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="packages.config" />
  </ItemGroup>
  <PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
  </PropertyGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
  <Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
    <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
  </Target>
  <ProjectExtensions>
    <VisualStudio>
      <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
        <WebProjectProperties>
          <UseIIS>True</UseIIS>
          <AutoAssignPort>True</AutoAssignPort>
          <DevelopmentServerPort>40646</DevelopmentServerPort>
          <DevelopmentServerVPath>/</DevelopmentServerVPath>
          <IISUrl>http://localhost:40646/</IISUrl>
          <NTLMAuthentication>False</NTLMAuthentication>
          <UseCustomServer>False</UseCustomServer>
          <CustomServerUrl>
          </CustomServerUrl>
          <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
        </WebProjectProperties>
      </FlavorProperties>
    </VisualStudio>
  </ProjectExtensions>
  <!-- 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> -->
  <ItemGroup>
    <F Include="test.txt">
      <OP>tst/</OP>
    </F>
    <F Include="test1.txt">
      <OP>tst/</OP>
    </F>
  </ItemGroup>
  <Target Name="HW" Inputs="@(F)" Outputs="@(F->'%(OP)%(Filename)%(Extension)')">
    <Message Text="%(F.OP)"/>
    <Copy SourceFiles="@(F)" DestinationFolder="%(F.OP)" />
  </Target>
</Project>
View Code

  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

复制代码
<Script Include="Script/jquery.js;Script/app.js">
  <Version>0.1</Version>
</Script>
<Target Name="Nothing">
  <Message Text="@(Script)+%(Script.Version)" />
</Target>
// 执行结果:Script/jquery.js;Script/app.js+01
复制代码

       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 最后访问时间

示例:

复制代码
<MyItem Include="HelloWorld.cs">
</MyItem>
<Target Name="Test">
  <Message Text="%(MyItem.FileName)"/>
</Target
// 输出 HelloWorld
复制代码

 *元数据转换(MSBuild Transform)* 

      增量生成就会用到MSBuild Transform。

      作用:将一组Item转换为一组输出值

  语法: @(ItemType->'%(metadata)') 

复制代码
<Target Name="CopyOutputs"
    Inputs="@(BuiltAssemblies)"
    Outputs="@(BuiltAssemblies -> '$(OutputPath)%(Filename)%(Extension)')">

    <Copy
        SourceFiles="@(BuiltAssemblies)"
        DestinationFolder="$(OutputPath)"/>
</Target>

假定BuiltAssemblies如下
<BuiltAssemblies Include="a.txt"></BuiltAssemblies>
<BuiltAssemblies Include="b.txt"></BuiltAssemblies>
<BuiltAssemblies Include="c.txt"></BuiltAssemblies>

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:配置信息的键值对

明细

示例

定义属性 <属性名>属性值</属性名> <buildMode>debug</buildMode>
调用 $(属性名) <Message Text="$(buildMode)"></Message>
注意 在启动执行引擎时,可从通过/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  生效条件
复制代码
<Target Name="Compile" DependsOnTargets="Resources">
    <Csc  Sources="@(CSFile)"
            TargetType="library"
            Resources="@(CompiledResources)"
            EmitDebugInformation="$(includeDebugInformation)"
            References="@(Reference)"
            DebugType="$(debuggingType)"
            OutputAssembly="$(builtdir)\$(MSBuildProjectName).dll" >
        <Output TaskParameter="OutputAssembly"
                  ItemName="FinalAssemblyName" />
        <Output TaskParameter="BuildSucceeded"
                  PropertyName="BuildWorked" />
    </Csc>
</Target>
复制代码

   分类:

分类 说明

示例

MSBuild内置任务执行程序 由MSBuild预定义的任务执行程序,如Csc、Message等 <Message Text="HelloWrold!"/>
外部任务执行程序 通过MSBuild内置任务执行程序Exec来调用操作系统内的任意程序来执行任务
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <Binaries Include="*.dll;*.exe"/>
    </ItemGroup>

    <Target Name="SetACL">
        <!-- set security on binaries-->
        <Exec Command="echo y| cacls %(Binaries.Identity) /G everyone:R"/>
    </Target>

</Project>
自定义任务执行程序 

继承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 参数类型

<ParameterGroup>
<Name ParameterType="System.String" Required="True"/>
<Age ParameterType="System.Integer" Required="True" Output="18"/>
</ParameterGroup>

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

子元素<![CDATA[代码]]>

任务实现的代码

       注意:当UsingTask中出现子元素Task时,则UsingTask的属性TaskFactory必须为CodeTaskFactory,AssemblyFile为$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll。

复制代码
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <UsingTask TaskName="Nothing" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
    <ParameterGroup/>
    <Task Type="Fragment" Language="cs">
            <Reference Include="System.Core"/>
              <Using Namespace="System" />
            <Using Namespace="System.IO" />
            <Using Namespace="System.Net" />
            <Using Namespace="Microsoft.Build.Framework" />
            <Using Namespace="Microsoft.Build.Utilities" />
            <Code Type="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;
                }
            ]]>
            </Code>
    </Task>
</Project>
复制代码

  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 <When Condition="'StringA' == 'StringB'">成立即生效</When>
Otherwise <Otherwise>所有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 <SolutionName>.sln /t:<ProjectName>:<TargetName>[;<ProjectName>:<TargetName>]* 

 

、小结                              

  本文主要是针对**.csproj中出现的元素来学习MSBuild Script,日后理论*实践后继续补充。

      尊重原创,转载请注明来自:^_^肥子John http://www.cnblogs.com/fsjohnhuang/p/4490562.html 

 

、参考                              

  https://msdn.microsoft.com/zh-cn/library/dd637714.aspx

 

如果您觉得本文的内容有趣就扫一下吧!捐赠互勉!

分类: .NET
8
0
« 上一篇: JS魔法堂:再识IE的内存泄露
» 下一篇: ES6 Features系列:Template Strings & Tagged Template Strings
posted @ 2015-05-12 14:18 ^_^肥仔John 阅读( 2371) 评论( 2) 编辑 收藏
  
#1楼 2015-05-13 10:01 Crayon  
这篇文章很棒,基本把VS的build功能讲解的很全了
  
#2楼 2015-12-29 11:29 Dolphinjiang  
我还以为是关注你的微信,可以将你的微信二维码贴上来啊
相关文章
|
2月前
|
存储 Shell Linux
快速上手基于 BaGet 的脚本自动化构建 .net 应用打包
本文介绍了如何使用脚本自动化构建 `.net` 应用的 `nuget` 包并推送到指定服务仓库。首先概述了 `BaGet`——一个开源、轻量级且高性能的 `NuGet` 服务器,支持多种存储后端及配置选项。接着详细描述了 `BaGet` 的安装、配置及使用方法,并提供了 `PowerShell` 和 `Bash` 脚本实例,用于自动化推送 `.nupkg` 文件。最后总结了 `BaGet` 的优势及其在实际部署中的便捷性。
107 10
|
3月前
|
设计模式 存储 前端开发
揭秘.NET架构设计模式:如何构建坚不可摧的系统?掌握这些,让你的项目无懈可击!
【8月更文挑战第28天】在软件开发中,设计模式是解决常见问题的经典方案,助力构建可维护、可扩展的系统。本文探讨了.NET中三种关键架构设计模式:MVC、依赖注入与仓储模式,并提供了示例代码。MVC通过模型、视图和控制器分离关注点;依赖注入则通过外部管理组件依赖提升复用性和可测性;仓储模式则统一数据访问接口,分离数据逻辑与业务逻辑。掌握这些模式有助于开发者优化系统架构,提升软件质量。
51 5
|
3月前
|
机器学习/深度学习 人工智能 算法
【悬念揭秘】ML.NET:那片未被探索的机器学习宝藏,如何让普通开发者一夜变身AI高手?——从零开始,揭秘构建智能应用的神秘旅程!
【8月更文挑战第28天】ML.NET 是微软推出的一款开源机器学习框架,专为希望在本地应用中嵌入智能功能的 .NET 开发者设计。无需深厚的数据科学背景,即可实现预测分析、推荐系统和图像识别等功能。它支持多种数据源,提供丰富的预处理工具和多样化的机器学习算法,简化了数据处理和模型训练流程。
47 1
|
3月前
|
存储 缓存 安全
.NET 在金融行业的应用:高并发交易系统的构建与优化之路
【8月更文挑战第28天】在金融行业,交易系统需具备高并发处理、低延迟及高稳定性和安全性。利用.NET构建此类系统时,可采用异步编程提升并发能力,优化数据库访问以降低延迟,使用缓存减少数据库访问频率,借助分布式事务确保数据一致性,并加强安全性措施。通过综合优化,满足金融行业的严苛要求。
45 1
|
3月前
|
大数据 开发工具 开发者
从零到英雄:.NET核心技术带你踏上编程之旅,构建首个应用,开启你的数字世界探险!
【8月更文挑战第28天】本文带领读者从零开始,使用强大的.NET平台搭建首个控制台应用。无论你是新手还是希望扩展技能的开发者,都能通过本文逐步掌握.NET的核心技术。从环境搭建到创建项目,再到编写和运行代码,详细步骤助你轻松上手。通过计算两数之和的小项目,你不仅能快速入门,还能为未来开发更复杂的应用奠定基础。希望本文为你的.NET学习之旅开启新篇章!
33 1
|
3月前
|
缓存 运维 前端开发
阿里云云效操作报错合集之如何解决在使用流水线构建net8应用时遇到无法构建的报错
本合集将整理呈现用户在使用过程中遇到的报错及其对应的解决办法,包括但不限于账户权限设置错误、项目配置不正确、代码提交冲突、构建任务执行失败、测试环境异常、需求流转阻塞等问题。阿里云云效是一站式企业级研发协同和DevOps平台,为企业提供从需求规划、开发、测试、发布到运维、运营的全流程端到端服务和工具支撑,致力于提升企业的研发效能和创新能力。
|
3月前
|
C# Windows 开发者
超越选择焦虑:深入解析WinForms、WPF与UWP——谁才是打造顶级.NET桌面应用的终极利器?从开发效率到视觉享受,全面解读三大框架优劣,助你精准匹配项目需求,构建完美桌面应用生态系统
【8月更文挑战第31天】.NET框架为开发者提供了多种桌面应用开发选项,包括WinForms、WPF和UWP。WinForms简单易用,适合快速开发基本应用;WPF提供强大的UI设计工具和丰富的视觉体验,支持XAML,易于实现复杂布局;UWP专为Windows 10设计,支持多设备,充分利用现代硬件特性。本文通过示例代码详细介绍这三种框架的特点,帮助读者根据项目需求做出明智选择。以下是各框架的简单示例代码,便于理解其基本用法。
110 0
|
3月前
|
Java Spring 自然语言处理
Spring 框架里竟藏着神秘魔法?国际化与本地化的奇妙之旅等你来揭开谜底!
【8月更文挑战第31天】在软件开发中,国际化(I18N)与本地化(L10N)对于满足不同地区用户需求至关重要。Spring框架提供了强大支持,利用资源文件和`MessageSource`实现多语言文本管理。通过配置日期格式和货币符号,进一步完善本地化功能。合理应用这些特性,可显著提升应用的多地区适应性和用户体验。
35 0
|
3月前
|
传感器 开发框架 物联网
揭开.NET在IoT领域的神秘面纱:如何构建智能设备,让未来生活触手可及?
【8月更文挑战第28天】随着物联网技术的发展,智能设备正深入我们的生活。.NET作为跨平台开源框架,在IoT领域应用广泛。本文介绍如何利用.NET构建智能设备,通过实例展示从环境搭建到项目创建、代码编写及运行的全过程,帮助开发者快速实现IoT解决方案,开启智能设备开发的新篇章。
43 0
|
3月前
|
开发框架 监控 .NET
开发者的革新利器:ASP.NET Core实战指南,构建未来Web应用的高效之道
【8月更文挑战第28天】本文探讨了如何利用ASP.NET Core构建高效、可扩展的Web应用。ASP.NET Core是一个开源、跨平台的框架,具有依赖注入、配置管理等特性。文章详细介绍了项目结构规划、依赖注入配置、中间件使用及性能优化方法,并讨论了安全性、可扩展性以及容器化的重要性。通过这些技术要点,开发者能够快速构建出符合现代Web应用需求的应用程序。
47 0