任務撰寫
工作會提供在建置過程中執行的程式碼。 工作包含在目標中。 常見任務庫隨 MSBuild 提供,您也可以建立自己的任務。 如需 MSBuild 隨附之工作連結庫的詳細資訊,請參閱 工作參考。
任務
工作的範例包括 複製,它會複製一或多個檔案、MakeDir、建立目錄,以及編譯 C# 原始碼檔案的 Csc。 每個工作都會實作為實作 ITask 介面的 .NET 類別,該介面定義於 Microsoft.Build.Framework.dll 元件中。
實作工作時可以使用兩種方法:
直接實作 ITask 介面。
從 helper 類別 Task衍生您的類別,該類別定義於 Microsoft.Build.Utilities.dll 元件中。 工作會實作 ITask,並提供某些 ITask 成員的預設實作。 此外,記錄也比較容易。
在這兩種情況下,您必須將名為 Execute
的方法新增至類別,這是工作執行時呼叫的方法。 此方法不接受任何參數,並傳回 Boolean
值:如果工作成功,則為 true
,如果工作失敗,則為 false
。 下列範例顯示未執行任何動作且順利完成的工作(傳回 true
)。
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace MyTasks
{
public class SimpleTask : Task
{
public override bool Execute()
{
return true;
}
}
}
下列項目檔會執行此工作:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MyTarget">
<SimpleTask />
</Target>
</Project>
當工作執行時,如果您在工作類別上建立 .NET 屬性,也可以從項目檔接收輸入。 MSBuild 會在呼叫工作的 Execute
方法之前,立即設定這些屬性。 若要建立字串屬性,請使用工作程式代碼,例如:
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace MyTasks
{
public class SimpleTask : Task
{
public override bool Execute()
{
return true;
}
public string MyProperty { get; set; }
}
}
下列項目檔會執行此工作,並將 MyProperty
設定為指定的值:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MyTarget">
<SimpleTask MyProperty="Value for MyProperty" />
</Target>
</Project>
註冊任務
如果專案要執行工作,MSBuild 必須知道如何找出並執行包含工作類別的元件。 工作使用 UsingTask 元素(MSBuild)註冊。
如果您的任務具有執行期間特定的相依性,您必須向 MSBuild 通知,它應該在特定環境中執行任務,方法是 在其 UsingTask中指定 Architecture
和/或 Runtime
。
MSBuild 檔案 Microsoft.Common.tasks 是項目檔,其中包含一份 UsingTask
專案清單,可註冊 MSBuild 提供的所有工作。 建置任何專案時,會自動包含此檔案。 如果已在 Microsoft.Common.tasks 中註冊的工作, 也會在目前的專案檔中註冊,則目前的項目檔會優先,因此您可以使用具有相同名稱的預設工作覆寫預設工作。
提示
要查看特定版本 MSBuild 所提供的工作清單,您可以檢視 Microsoft.Common.tasks的內容。
從任務引發事件
如果您的任務源自 Task 協助程式類別,您可以在 Task 類別上使用下列任何協助程式方法來觸發事件,這些事件將被任何已註冊的記錄器攔截並顯示:
public override bool Execute()
{
Log.LogError("messageResource1", "1", "2", "3");
Log.LogWarning("messageResource2");
Log.LogMessage(MessageImportance.High, "messageResource3");
...
}
如果你的任務直接實現 ITask,你仍然可以引發這類事件,但必須使用 IBuildEngine 介面。 下列範例顯示實作 ITask 並引發自定義事件的工作:
public class SimpleTask : ITask
{
public IBuildEngine BuildEngine { get; set; }
public override bool Execute()
{
TaskEventArgs taskEvent =
new TaskEventArgs(BuildEventCategory.Custom,
BuildEventImportance.High, "Important Message",
"SimpleTask");
BuildEngine.LogBuildEvent(taskEvent);
return true;
}
}
需要設定工作參數
您可以將某些工作屬性標示為「必要」,讓執行工作的任何專案檔都必須設定這些屬性的值,否則組建會失敗。 將 [Required]
屬性套用至工作中的 .NET 屬性,如下所示:
[Required]
public string RequiredProperty { get; set; }
[Required]
屬性是由 Microsoft.Build.Framework 命名空間中的 RequiredAttribute 所定義。
MSBuild 如何叫用任務
叫用工作時,MSBuild 會先將工作類別實體化,然後針對在專案檔內 task 元素中設定的工作參數,呼叫該物件的屬性設定器。 如果工作元素未指定參數,或專案中指定的表達式評估為空字串,則不會呼叫屬性 setter。
例如,在專案中
<Project>
<Target Name="InvokeCustomTask">
<CustomTask Input1=""
Input2="$(PropertyThatIsNotDefined)"
Input3="value3" />
</Target>
</Project>
只會呼叫 Input3
的 setter。
工作不應相依於參數屬性 setter 調用的任何相對順序。
工作參數類型
MSBuild 會以原生方式處理類型 string
、 bool
、 ITaskItem
和 ITaskItem[]
的屬性。 如果作業接受不同類型的參數,MSBuild 會叫用 ChangeType,以從 string
(所有屬性和專案的引用已展開)轉換至目標類型。 如果任何輸入參數的轉換失敗,MSBuild 會發出錯誤,而且不會呼叫工作的 Execute()
方法。
任務打包
分發任務的建議方式是透過 NuGet 套件。 套件必須包含所有的相依項目。 本主題會在逐步引導您建立自定義工作的教學課程中徹底說明。 請參閱「建立 NuGet 套件」。
範例 1
描述
下列 C# 類別示範衍生自 Task 協助程式類別的工作。 此工作會傳回 true
,表示它成功。
代碼
using System;
using Microsoft.Build.Utilities;
namespace SimpleTask1
{
public class SimpleTask1: Task
{
public override bool Execute()
{
// This is where the task would presumably do its work.
return true;
}
}
}
範例 2
描述
下列 C# 類別示範實作 ITask 介面的工作。 此工作會傳回 true
,表示它成功。
代碼
using System;
using Microsoft.Build.Framework;
namespace SimpleTask2
{
public class SimpleTask2: ITask
{
//When implementing the ITask interface, it is necessary to
//implement a BuildEngine property of type
//Microsoft.Build.Framework.IBuildEngine. This is done for
//you if you derive from the Task class.
public IBuildEngine BuildEngine { get; set; }
// When implementing the ITask interface, it is necessary to
// implement a HostObject property of type object.
// This is done for you if you derive from the Task class.
public object HostObject { get; set; }
public bool Execute()
{
// This is where the task would presumably do its work.
return true;
}
}
}
範例 3
描述
這個 C# 類別示範衍生自協助程式類別 Task 的工作。 它具有必要的字符串屬性,並引發一個事件,該事件由所有已註冊的記錄器顯示。
代碼
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace SimpleTask3
{
public class SimpleTask3 : Task
{
private string myProperty;
// The [Required] attribute indicates a required property.
// If a project file invokes this task without passing a value
// to this property, the build will fail immediately.
[Required]
public string MyProperty
{
get
{
return myProperty;
}
set
{
myProperty = value;
}
}
public override bool Execute()
{
// Log a high-importance comment
Log.LogMessage(MessageImportance.High,
"The task was passed \"" + myProperty + "\".");
return true;
}
}
}
範例 4
描述
下列範例顯示一個專案檔案如何叫用之前的範例任務 SimpleTask3。
程式碼
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="SimpleTask3.SimpleTask3"
AssemblyFile="SimpleTask3\bin\debug\simpletask3.dll"/>
<Target Name="MyTarget">
<SimpleTask3 MyProperty="Hello!"/>
</Target>
</Project>