文章出處

一、前言                            

  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

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()