• .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>..packagesEntityFramework.5.0.0lib
    et40EntityFramework.dll</HintPath>
        </Reference>
        <Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
          <Private>True</Private>
          <HintPath>..packagesMicrosoft.Web.Infrastructure.1.0.0.0lib
    et40Microsoft.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>..packagesMicrosoft.AspNet.Mvc.FixedDisplayModes.1.0.0lib
    et40Microsoft.Web.Mvc.FixedDisplayModes.dll</HintPath>
        </Reference>
        <Reference Include="Newtonsoft.Json">
          <HintPath>..packagesNewtonsoft.Json.4.5.11lib
    et40Newtonsoft.Json.dll</HintPath>
        </Reference>
        <Reference Include="System.Net.Http">
          <Private>True</Private>
          <HintPath>..packagesMicrosoft.Net.Http.2.0.30506.0lib
    et40System.Net.Http.dll</HintPath>
        </Reference>
        <Reference Include="System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
          <HintPath>..packagesMicrosoft.AspNet.WebApi.Client.4.0.30506.0lib
    et40System.Net.Http.Formatting.dll</HintPath>
        </Reference>
        <Reference Include="System.Net.Http.WebRequest">
          <Private>True</Private>
          <HintPath>..packagesMicrosoft.Net.Http.2.0.30506.0lib
    et40System.Net.Http.WebRequest.dll</HintPath>
        </Reference>
        <Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
          <HintPath>..packagesMicrosoft.AspNet.WebApi.Core.4.0.30506.0lib
    et40System.Web.Http.dll</HintPath>
        </Reference>
        <Reference Include="System.Web.Http.WebHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
          <HintPath>..packagesMicrosoft.AspNet.WebApi.WebHost.4.0.30506.0lib
    et40System.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>..packagesMicrosoft.AspNet.Mvc.4.0.30506.0lib
    et40System.Web.Mvc.dll</HintPath>
        </Reference>
        <Reference Include="System.Web.Optimization">
          <HintPath>..packagesMicrosoft.AspNet.Web.Optimization.1.0.0lib
    et40System.Web.Optimization.dll</HintPath>
        </Reference>
        <Reference Include="System.Web.Providers">
          <HintPath>..packagesMicrosoft.AspNet.Providers.Core.1.2lib
    et40System.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>..packagesMicrosoft.AspNet.Razor.2.0.30506.0lib
    et40System.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>..packagesMicrosoft.AspNet.WebPages.2.0.30506.0lib
    et40System.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>..packagesMicrosoft.AspNet.WebPages.2.0.30506.0lib
    et40System.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>..packagesMicrosoft.AspNet.WebPages.2.0.30506.0lib
    et40System.Web.WebPages.Razor.dll</HintPath>
        </Reference>
        <Reference Include="WebGrease">
          <Private>True</Private>
          <HintPath>..packagesWebGrease.1.3.0libWebGrease.dll</HintPath>
        </Reference>
        <Reference Include="Antlr3.Runtime">
          <Private>True</Private>
          <HintPath>..packagesWebGrease.1.3.0libAntlr3.Runtime.dll</HintPath>
        </Reference>
      </ItemGroup>
      <ItemGroup>
        <Compile Include="App_StartBundleConfig.cs" />
        <Compile Include="App_StartFilterConfig.cs" />
        <Compile Include="App_StartRouteConfig.cs" />
        <Compile Include="App_StartWebApiConfig.cs" />
        <Compile Include="Global.asax.cs">
          <DependentUpon>Global.asax</DependentUpon>
        </Compile>
        <Compile Include="PropertiesAssemblyInfo.cs" />
      </ItemGroup>
      <ItemGroup>
        <Content Include="Content	hemesaseimagesui-bg_flat_0_aaaaaa_40x100.png" />
        <Content Include="Content	hemesaseimagesui-bg_flat_75_ffffff_40x100.png" />
        <Content Include="Content	hemesaseimagesui-bg_glass_55_fbf9ee_1x400.png" />
        <Content Include="Content	hemesaseimagesui-bg_glass_65_ffffff_1x400.png" />
        <Content Include="Content	hemesaseimagesui-bg_glass_75_dadada_1x400.png" />
        <Content Include="Content	hemesaseimagesui-bg_glass_75_e6e6e6_1x400.png" />
        <Content Include="Content	hemesaseimagesui-bg_glass_95_fef1ec_1x400.png" />
        <Content Include="Content	hemesaseimagesui-bg_highlight-soft_75_cccccc_1x100.png" />
        <Content Include="Content	hemesaseimagesui-icons_222222_256x240.png" />
        <Content Include="Content	hemesaseimagesui-icons_2e83ff_256x240.png" />
        <Content Include="Content	hemesaseimagesui-icons_454545_256x240.png" />
        <Content Include="Content	hemesaseimagesui-icons_888888_256x240.png" />
        <Content Include="Content	hemesaseimagesui-icons_cd0a0a_256x240.png" />
        <Content Include="Content	hemesasejquery-ui.css" />
        <Content Include="Content	hemesasejquery.ui.accordion.css" />
        <Content Include="Content	hemesasejquery.ui.all.css" />
        <Content Include="Content	hemesasejquery.ui.autocomplete.css" />
        <Content Include="Content	hemesasejquery.ui.base.css" />
        <Content Include="Content	hemesasejquery.ui.button.css" />
        <Content Include="Content	hemesasejquery.ui.core.css" />
        <Content Include="Content	hemesasejquery.ui.datepicker.css" />
        <Content Include="Content	hemesasejquery.ui.dialog.css" />
        <Content Include="Content	hemesasejquery.ui.progressbar.css" />
        <Content Include="Content	hemesasejquery.ui.resizable.css" />
        <Content Include="Content	hemesasejquery.ui.selectable.css" />
        <Content Include="Content	hemesasejquery.ui.slider.css" />
        <Content Include="Content	hemesasejquery.ui.tabs.css" />
        <Content Include="Content	hemesasejquery.ui.theme.css" />
        <Content Include="Content	hemesaseminifiedimagesui-bg_flat_0_aaaaaa_40x100.png" />
        <Content Include="Content	hemesaseminifiedimagesui-bg_flat_75_ffffff_40x100.png" />
        <Content Include="Content	hemesaseminifiedimagesui-bg_glass_55_fbf9ee_1x400.png" />
        <Content Include="Content	hemesaseminifiedimagesui-bg_glass_65_ffffff_1x400.png" />
        <Content Include="Content	hemesaseminifiedimagesui-bg_glass_75_dadada_1x400.png" />
        <Content Include="Content	hemesaseminifiedimagesui-bg_glass_75_e6e6e6_1x400.png" />
        <Content Include="Content	hemesaseminifiedimagesui-bg_glass_95_fef1ec_1x400.png" />
        <Content Include="Content	hemesaseminifiedimagesui-bg_highlight-soft_75_cccccc_1x100.png" />
        <Content Include="Content	hemesaseminifiedimagesui-icons_222222_256x240.png" />
        <Content Include="Content	hemesaseminifiedimagesui-icons_2e83ff_256x240.png" />
        <Content Include="Content	hemesaseminifiedimagesui-icons_454545_256x240.png" />
        <Content Include="Content	hemesaseminifiedimagesui-icons_888888_256x240.png" />
        <Content Include="Content	hemesaseminifiedimagesui-icons_cd0a0a_256x240.png" />
        <Content Include="Content	hemesaseminifiedjquery-ui.min.css" />
        <Content Include="Content	hemesaseminifiedjquery.ui.accordion.min.css" />
        <Content Include="Content	hemesaseminifiedjquery.ui.autocomplete.min.css" />
        <Content Include="Content	hemesaseminifiedjquery.ui.button.min.css" />
        <Content Include="Content	hemesaseminifiedjquery.ui.core.min.css" />
        <Content Include="Content	hemesaseminifiedjquery.ui.datepicker.min.css" />
        <Content Include="Content	hemesaseminifiedjquery.ui.dialog.min.css" />
        <Content Include="Content	hemesaseminifiedjquery.ui.progressbar.min.css" />
        <Content Include="Content	hemesaseminifiedjquery.ui.resizable.min.css" />
        <Content Include="Content	hemesaseminifiedjquery.ui.selectable.min.css" />
        <Content Include="Content	hemesaseminifiedjquery.ui.slider.min.css" />
        <Content Include="Content	hemesaseminifiedjquery.ui.tabs.min.css" />
        <Content Include="Content	hemesaseminifiedjquery.ui.theme.min.css" />
        <Content Include="Global.asax" />
        <Content Include="ContentSite.css" />
        <None Include="Scriptsjquery-1.8.2.intellisense.js" />
        <Content Include="Scriptsjquery-1.8.2.js" />
        <Content Include="Scriptsjquery-1.8.2.min.js" />
        <None Include="Scriptsjquery.validate-vsdoc.js" />
        <Content Include="Scriptsjquery-ui-1.8.24.js" />
        <Content Include="Scriptsjquery-ui-1.8.24.min.js" />
        <Content Include="Scriptsjquery.unobtrusive-ajax.js" />
        <Content Include="Scriptsjquery.unobtrusive-ajax.min.js" />
        <Content Include="Scriptsjquery.validate.js" />
        <Content Include="Scriptsjquery.validate.min.js" />
        <Content Include="Scriptsjquery.validate.unobtrusive.js" />
        <Content Include="Scriptsjquery.validate.unobtrusive.min.js" />
        <Content Include="Scriptsknockout-2.2.0.debug.js" />
        <Content Include="Scriptsknockout-2.2.0.js" />
        <Content Include="Scriptsmodernizr-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="ViewsWeb.config" />
        <Content Include="Views\_ViewStart.cshtml" />
        <Content Include="ViewsSharedError.cshtml" />
        <Content Include="ViewsShared\_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)MicrosoftVisualStudiov$(VisualStudioVersion)</VSToolsPath>
      </PropertyGroup>
      <Import Project="$(MSBuildBinPath)Microsoft.CSharp.targets" />
      <Import Project="$(VSToolsPath)WebApplicationsMicrosoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
      <Import Project="$(MSBuildExtensionsPath32)MicrosoftVisualStudiov10.0WebApplicationsMicrosoft.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(时间戳) <-> bina.txt(时间戳)
    b.txt(时间戳) <-> bin.txt(时间戳)
    c.txt(时间戳) <-> binc.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

  • 相关阅读:
    30 个最好的jQuery表单插件
    Jquery Tools——不可错过的Jquery UI库(三)
    RedHat Linux AS5安装Oracle 10g 及常见问题
    老婆一直在你身旁,写给咱们的孩子
    又一篇关于中航信的文章
    Java自定义异常
    php文件复制升级
    PHP文件复制
    hdu 2428
    hdu 1358 KMP的应用
  • 原文地址:https://www.cnblogs.com/fsjohnhuang/p/4490562.html
Copyright © 2020-2023  润新知