タスクの作成
タスクでは、ビルド プロセスの間に実行するコードを指定します。 タスクはターゲットに含まれます。 一般的なタスクのライブラリは MSBuild に付属します。また、独自のタスクを作成することもできます。 MSBuild に付属するタスクのライブラリの詳細については、タスク リファレンスを参照してください。
タスク
タスクの例としては、1 つまたは複数のファイルをコピーする Copy、ディレクトリを作成する MakeDir、C# ソース コード ファイルをコンパイルする Csc などがあります。 各タスクは、Microsoft.Build.Framework.dll アセンブリで定義されている ITask インターフェイスを実装する .NET クラスとして実装されます。
タスクを実装するには 2 つの方法があります。
ITask インターフェイスを直接実装します。
Microsoft.Build.Utilities.dll アセンブリで定義されているヘルパー クラス Task からクラスを継承します。 Task は 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) で登録されます。
タスクにランタイム固有の依存関係がある場合は、その UsingTask で Architecture
や Runtime
を指定することにより、特定の環境でタスクを実行する必要があることを MSBuild に通知する必要があります。
MSBuild ファイルの Microsoft.Common.tasks は、MSBuild に付属するすべてのタスクを登録する UsingTask
要素の一覧が含まれるプロジェクト ファイルです。 このファイルは、あらゆるプロジェクトのビルド時に自動的に追加されます。 Microsoft.Common.tasks に登録されているタスクが現在のプロジェクト ファイルにも登録されている場合、現在のプロジェクト ファイルに優先権が与えられます。したがって、既定のタスクを、同じ名前を持つ独自のタスクでオーバーライドできます。
ヒント
その Microsoft.Common.tasks のコンテンツを表示することで、MSBuild の特定のバージョンに付属するタスクの一覧を確認できます。
タスクからイベントを生成する
タスクが 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;
}
}
タスク パラメーターの設定を要求する
特定のタスク プロパティを "必須" に設定できます。必須にすると、タスクを実行するプロジェクト ファイルで、必須のプロパティに値を設定する必要があります。設定しないと、ビルドに失敗します。 次のように、タスクの .NET プロパティに [Required]
属性を適用します。
[Required]
public string RequiredProperty { get; set; }
[Required]
属性は Microsoft.Build.Framework 名前空間の RequiredAttribute によって定義されます。
MSBuild によるタスクの呼び出し方法
タスクを呼び出すと、まず MSBuild によってタスク クラスがインスタンス化され、次にプロジェクト ファイルのタスク要素内に設定されているタスク パラメーター用のオブジェクトのプロパティ セッターが呼び出されます。 タスク要素によってパラメーターが指定されていない場合、または要素内で指定された式によって空の文字列であると評価された場合、プロパティ セッターは呼び出されません。
たとえば、プロジェクトでは次のようになります
<Project>
<Target Name="InvokeCustomTask">
<CustomTask Input1=""
Input2="$(PropertyThatIsNotDefined)"
Input3="value3" />
</Target>
</Project>
Input3
のセッターのみが呼び出されます。
タスクは、パラメータープロパティ セッター呼び出しの相対順序に依存しないようにする必要があります。
タスク パラメーターの型
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>