MSBuild 內嵌工作
MSBuild 工作的建立方式通常是編譯可實作 ITask 介面的類別。 如需詳細資訊,請參閱MSBuild 工作。
在 .NET Framework 第 4 版中,您可以在專案檔中建立內嵌工作。 您不用建立個別的組件,便可裝載工作。 如此一來,即可更輕鬆地追蹤原始程式碼及部署工作。 原始程式碼已整合成為指令碼。
內嵌工作的結構
內嵌工作包含在 UsingTask 項目之內。 內嵌工作與其所在的 UsingTask 項目通常會包含在 .targets 檔中,並視需要匯入到其他專案檔中。 以下是基本的內嵌工作。 請注意,它不會有任何作用。
<Project ToolsVersion="4.0" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
<!-- This simple inline task does nothing. -->
<UsingTask
TaskName="DoNothing"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup />
<Task>
<Reference Include="" />
<Using Namespace="" />
<Code Type="Fragment" Language="cs">
</Code>
</Task>
</UsingTask>
</Project>
範例中的 UsingTask 項目具有三個屬性,可描述工作以及編譯該工作的內嵌工作 Factory。
TaskName 屬性會命名工作,在此案例中,則命名為 DoNothing。
TaskFactory 屬性會命名可實作內嵌工作 Factory 的類別。
AssemblyFile 屬性會提供內嵌工作 Factory 的位置。 或者,您可以使用 AssemblyName 屬性來指定內嵌工作 Factory 類別的完整名稱,它通常位於全域組件快取 (GAC) 中。
DoNothing 工作的其餘項目是空的,可供用於說明內嵌工作的順序和結構。 本主題稍後會提供更健全的範例。
ParameterGroup 項目是選擇性的。 若已指定,它會宣告工作的參數。 如需輸入和輸出參數的詳細資訊,請參閱本主題中後面的<輸入和輸出參數>。
Task 項目可描述及包含工作原始程式碼。
Reference 項目可指定您用於程式碼中的 .NET 組件的參考。 這等同於在 Visual Studio 中將參考加入到專案。 Include 屬性可指定參考組件的路徑。
Using 項目可列出您想存取的命名空間。 這類似於 Visual C# 中的 Using 陳述式。 Namespace 屬性可指定要包含的命名空間。
Reference 和 Using 項目與語言無關。 內嵌工作可以使用任何一種受支援的 .NET CodeDom 語言來撰寫,例如:Visual Basic、Visual C# 和 JScript。
注意事項 |
---|
Task 內含的項目專屬於工作 Factory,在此案例中為程式碼工作 Factory。 |
Code 項目
Task 項目內顯示的最後一個子項目為 Code 項目。 Code 項目可包含或找出您要編譯成工作的程式碼。 您放入 Code 項目中的內容取決於您撰寫工作的方式。
Language 屬性可指定用於撰寫程式碼的語言。 可接受的值為 cs (適用於 C#)、vb (適用於 Visual Basic),和 js (適用於 JScript)。
Type 屬性可指定在 Code 項目中找到的程式碼類型。
如果 Type 的值為 Class,則 Code 項目會包含衍生自 ITask 介面之類別的程式碼。
如果 Type 的值為 Method,則程式碼會定義 ITask 介面之 Execute 方法的覆寫。
如果 Type 的值為 Fragment,則程式碼會定義 Execute 方法的內容,但並非簽章或 return 陳述式。
程式碼本身通常會出現於 <![CDATA[ 標記和 ]]> 標記之間。 因為此程式碼是在 CDATA 區段中,所以您不必擔心逸出保留的字元,如 "<" 或 ">"。
或者,您可以使用 Code 項目的 Source 屬性,指定含有工作程式碼的檔案位置。 原始程式檔中的程式碼必須是 Type 屬性所指定的類型。 如果 Source 屬性存在,則 Type 的預設值為 Class。 如果 Source 不存在,預設值為 Fragment。
注意事項 |
---|
在原始程式檔中定義工作類別時,類別名稱必須符合對應 UsingTask 項目的 TaskName 屬性。 |
Hello World
以下是更健全的內嵌工作。 HelloWorld 工作會在預設錯誤記錄裝置上顯示 "Hello, world!",此裝置通常是系統主控台或 Visual Studio 的 [輸出] 視窗。 範例中包含的 Reference 項目僅供說明之用。
<Project ToolsVersion="4.0" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
<!-- This simple inline task displays "Hello, world!" -->
<UsingTask
TaskName="HelloWorld"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup />
<Task>
<Reference Include="System.Xml.dll"/>
<Using Namespace="System"/>
<Using Namespace="System.IO"/>
<Code Type="Fragment" Language="cs">
<![CDATA[
// Display "Hello, world!"
Log.LogError("Hello, world!");
]]>
</Code>
</Task>
</UsingTask>
</Project>
您可以將 HelloWorld 工作儲存於名為 HelloWorld.targets 的檔案中,然後如下所述從專案進行叫用。
<Project ToolsVersion="4.0" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="HelloWorld.targets" />
<Target Name="Hello">
<HelloWorld />
</Target>
</Project>
輸入和輸出參數
內嵌工作參數是 ParameterGroup 項目的子項目。 每個參數都會採用定義該參數的項目名稱。 下列程式碼定義參數 Text。
<ParameterGroup>
<Text />
</ParameterGroup>
參數可以有下列其中一個或多個屬性:
Required 是預設為 false 的選擇性屬性。 若為 true,此參數則為必要參數,而且必須在呼叫工作之前提供值給它。
ParameterType 是預設為 System.String 的選擇性屬性。 它可以設定為任何完整類型,而此類型是可使用 System.Convert.ChangeType 與字串互相轉換的項目或值 (換言之,可以從外部工作來回傳遞的任何類型)。
Output 是預設為 false 的選擇性屬性。 若為 true,則在從 Execute 方法傳回之前必須提供值給此參數。
例如:
<ParameterGroup>
<Expression Required="true" />
<Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<Tally ParameterType="System.Int32" Output="true" />
</ParameterGroup>
會定義下列三個參數:
Expression 是類型為 System.String 的必要輸入參數。
Files 是必要的項目清單輸入參數。
Tally 是類型為 System.Int32 的輸出參數。
如果 Code 項目具有 Fragment 或 Method 的 Type 屬性 (Attribute),則會自動建立每個參數的屬性 (Property)。 否則,必須在工作原始程式碼中明確地宣告屬性 (Property),而且必須完全符合其參數定義。
範例
下列內嵌工作會在指定的檔案中取代每一個具有指定值的語彙基元。
<Project xmlns='https://schemas.microsoft.com/developer/msbuild/2003' ToolsVersion="4.0">
<UsingTask TaskName="TokenReplace" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<Path ParameterType="System.String" Required="true" />
<Token ParameterType="System.String" Required="true" />
<Replacement ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs"><![CDATA[
string content = File.ReadAllText(Path);
content = content.Replace(Token, Replacement);
File.WriteAllText(Path, content);
]]></Code>
</Task>
</UsingTask>
<Target Name='Demo' >
<TokenReplace Path="C:\Project\Target.config" Token="$MyToken$" Replacement="MyValue"/>
</Target>
</Project>