逐步解說:建立內嵌工作
MSBuild 工作的建立方式通常是編譯可實作 ITask 介面的類別。 從 .NET Framework 第 4 版開始,您可以在專案檔中建立內嵌工作。 您不用建立個別的組件,便可裝載工作。 如需詳細資訊,請參閱 MSBuild 內嵌工作。
這個逐步解說示範如何建立及執行下列內嵌工作:
沒有輸入或輸出參數的工作。
有一個輸入參數但沒有輸出參數的工作。
有兩個輸入參數,以及一個可傳回 MSBuild 屬性 (Property) 之輸出參數的工作。
有兩個輸入參數,以及一個可傳回 MSBuild 項目 (Item) 之輸出參數的工作。
若要建立並執行工作,請使用 Visual Studio 和 [Visual Studio 命令提示字元視窗],如下所示:
使用 Visual Studio 建立 MSBuild 專案檔。
在 Visual Studio 中修改專案檔,以建立內嵌工作。
使用 [命令提示字元視窗] 來建立專案及檢查結果。
建立和修改 MSBuild 專案
Visual Studio 專案系統是以 MSBuild 為基礎。 因此,您可以使用 Visual Studio 建立建置專案檔。 在本章節中,您會建立 Visual C# 專案檔。 (您也可以建立 Visual Basic 專案檔。 在此教學課程中,這兩個專案檔之間的差異並不顯著)。
若要建立及修改專案檔
按一下 Visual Studio [檔案] 功能表上的 [新增],然後按一下 [專案]。
在 [新增專案] 對話方塊中,選取 Visual C# 專案類型,然後選取 [Windows Form 應用程式] 範本。 在 [名稱] 方塊中,輸入 InlineTasks。 輸入方案的 [位置],例如 D:\。 確定 [為方案建立目錄] 已選取、[加入至原始檔控制] 已清除,而且 [方案名稱] 為 InlineTasks。
按一下 [確定] 建立專案檔。
以滑鼠右鍵按一下 [方案總管] 中的 InlineTasks 專案節點,然後按一下 [卸載專案]。
再次以滑鼠右鍵按一下專案節點,然後按一下 [編輯 InlineTasks.csproj]。
專案檔會顯示在程式碼編輯器中。
加入基本 Hello 工作
現在,將可顯示 "Hello, world!" 訊息的基本工作加入至專案檔, 並加入預設 TestBuild 目標以叫用此工作。
若要加入基本 Hello 工作
在 Project 根節點中,將 DefaultTargets 屬性 (Attribute) 變更為 TestBuild。結果產生的 Project 節點應類似下列範例:
<Project ToolsVersion="4.0" DefaultTargets="TestBuild" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
將下列內嵌工作和目標加入至專案檔中,緊接在 </Project> 標記之前。
<UsingTask TaskName="Hello" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" > <ParameterGroup /> <Task> <Code Type="Fragment" Language="cs"> Log.LogMessage("Hello, world!", MessageImportance.High); </Code> </Task> </UsingTask> <Target Name="TestBuild"> <Hello /> </Target>
儲存專案檔案。
此程式碼會建立名為 Hello 的內嵌工作,而此工作並沒有參數、參考或 Using 陳述式。 Hello 工作只包含一行程式碼,此程式碼會在預設記錄裝置 (通常為主控台視窗) 上顯示 Hello 訊息。
執行 Hello 工作
使用 [命令提示字元視窗] 建構 Hello 工作及處理可叫用此工作的 TestBuild 目標,以便執行 MSBuild。
若要執行 Hello 工作
依序按一下 [開始]、[所有程式],然後找到 [Visual Studio Tools] 資料夾,並且按一下 [Visual Studio 命令提示字元]。
在 [命令提示字元視窗] 中,找到含有專案檔的資料夾 (在此案例中為 D:\InlineTasks\InlineTasks\)。
輸入不含命令參數的 msbuild,然後按 ENTER。 根據預設,這會建置 InlineTasks.csproj 檔以及處理可叫用 Hello 工作的預設目標 TestBuild。
檢查 [命令提示字元視窗] 中的輸出。 您應該會看見此行:
Hello, world!
注意事項 如果您沒有看到 Hello 訊息,請試著再次儲存專案檔,然後執行 Hello 工作。
交替使用程式碼編輯器和 [命令提示字元視窗],您即可變更專案檔而且迅速看到結果。
定義 Echo 工作
建立一個可接受字串參數並且在預設記錄裝置上顯示字串的內嵌工作。
若要定義 Echo 工作
在程式碼編輯器中,使用下列程式碼取代 Hello 工作和 TestBuild 目標。
<UsingTask TaskName="Echo" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" > <ParameterGroup> <Text Required="true" /> </ParameterGroup> <Task> <Code Type="Fragment" Language="cs"> Log.LogMessage(Text, MessageImportance.High); </Code> </Task> </UsingTask> <Target Name="TestBuild"> <Echo Text="Greetings!" /> </Target>
在 [命令提示字元視窗] 中,輸入不含命令參數的 msbuild,然後按 ENTER。 根據預設,這會處理可叫用 Echo 工作的預設目標 TestBuild。
檢查 [命令提示字元視窗] 中的輸出。 您應該會看見此行:
Greetings!
此程式碼會定義名為 Echo 且只有一個必要輸入參數 Text 的內嵌工作。 參數的類型預設為 System.String。 Text 參數的值會在 TestBuild 目標叫用 Echo 工作時設定。
定義 Adder 工作
建立一個可將兩個整數參數相加並以 MSBuild 屬性 (Property) 的形式發出其加總的內嵌工作。
若要定義 Adder 工作
在程式碼編輯器中,使用下列程式碼取代 Echo 工作和 TestBuild 目標。
<UsingTask TaskName="Adder" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" > <ParameterGroup> <A ParameterType="System.Int32" Required="true" /> <B ParameterType="System.Int32" Required="true" /> <C ParameterType="System.Int32" Output="true" /> </ParameterGroup> <Task> <Code Type="Fragment" Language="cs"> C = A + B; </Code> </Task> </UsingTask> <Target Name="TestBuild"> <Adder A="4" B="5"> <Output PropertyName="Sum" TaskParameter="C" /> </Adder> <Message Text="The sum is $(Sum)" Importance="High" /> </Target>
在 [命令提示字元視窗] 中,輸入不含命令參數的 msbuild,然後按 ENTER。 根據預設,這會處理可叫用 Echo 工作的預設目標 TestBuild。
檢查 [命令提示字元視窗] 中的輸出。 您應該會看見此行:
The sum is 9
此程式碼會定義一個名為 Adder 的內嵌工作,而此工作有兩個必要整數輸入參數 (A 和 B) 以及一個整數輸出參數 (C)。 Adder 工作會將兩個輸入參數相加並以輸出參數傳回加總。 加總會以 MSBuild 屬性 (Property) Sum 的形式發出。 輸入參數的值會在 TestBuild 目標叫用 Adder 工作時設定。
定義 RegX 工作
建立一個可接受項目 (Item) 群組和規則運算式的內嵌工作,此工作會傳回檔案內容符合運算式的所有項目清單。
若要定義 RegX 工作
在程式碼編輯器中,使用下列程式碼取代 Adder 工作和 TestBuild 目標。
<UsingTask TaskName="RegX" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" > <ParameterGroup> <Expression Required="true" /> <Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" /> <Result ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" /> </ParameterGroup> <Task> <Using Namespace="System.Text.RegularExpressions"/> <Code Type="Fragment" Language="cs"> <![CDATA[ if (Files.Length > 0) { Result = new TaskItem[Files.Length]; for (int i = 0; i < Files.Length; i++) { ITaskItem item = Files[i]; string path = item.GetMetadata("FullPath"); using(StreamReader rdr = File.OpenText(path)) { if (Regex.Match(rdr.ReadToEnd(), Expression).Success) { Result[i] = new TaskItem(item.ItemSpec); } } } } ]]> </Code> </Task> </UsingTask> <Target Name="TestBuild"> <RegX Expression="public|protected" Files="@(Compile)"> <Output ItemName="MatchedFiles" TaskParameter="Result" /> </RegX> <Message Text="Input files: @(Compile)" Importance="High" /> <Message Text="Matched files: @(MatchedFiles)" Importance="High" /> </Target>
在 [命令提示字元視窗] 中,輸入不含命令參數的 msbuild,然後按 ENTER。 根據預設,這會處理可叫用 RegX 工作的預設目標 TestBuild。
檢查 [命令提示字元視窗] 中的輸出。 您應該會看見下列各行:
Input files: Form1.cs;Form1.Designer.cs;Program.cs;Properties\AssemblyInfo.cs;Properties\Resources.Designer.cs;Properties\Settings.Designer.cs
Matched files: Form1.cs;Form1.Designer.cs;Properties\Settings.Designer.cs
此程式碼會定義名為 RegX 且具有下列三個參數的內嵌工作:
Expression 是必要的字串輸入參數,而它的值就是將要比對的規則運算式。 在此範例中,運算式會比對文字 "public" 或 "protected"。
Files 是必要的項目清單輸入參數,而它的值就是比對時所要搜尋的檔案清單。 在此範例中,Files 會設為 Compile 項目,以列出專案原始程式檔。
Result 是一個輸出參數,而它的值就是內容符合規則運算式的檔案清單。
輸入參數的值會在 TestBuild 目標叫用 RegX 工作時設定。 RegX 工作會讀取每一個檔案並傳回符合規則運算式的檔案清單。 此清單會以 Result 輸出參數的形式傳回,而該參數會以 MSBuild 項目 MatchedFiles 的形式發出。
處理保留的字元
MSBuild 剖析器會以 XML 形式處理內嵌工作。 在 XML 中有保留涵義的字元 (如 "<" 和 ">") 會視為 XML 而非 .NET 原始程式碼進行偵測和處理。 若要在程式碼運算式中納入保留的字元 (如 Files.Length > 0),請寫入 Code 項目 (Element),使其內容包含在 CDATA 運算式中,如下所示:
<Code Type="Fragment" Language="cs">
<![CDATA[
// Your code goes here.
]]>
</Code>