PowerShell スクリプトでエラーが発生したときにビルドを中断する 2 つの方法を次に示します。
exit()
PowerShell プロセスを終了するために使用します
ゼロ以外の場合にエラー リストに表示されるスクリプトからステータス コードを返すには、次を使用します。
exit(45) # or any other non-zero number, for that matter.
これは、エラー リストにエラー テキストを正確に取得するわけではありませんが、スクリプトを終了し、ビルド前またはビルド後のコマンドが失敗したことを示すエラー リストに何かを取得します。
カスタム MSBuild タスクを使用して PowerShell スクリプトを実行する
MSBuild タスク内で PowerShell スクリプトを実行する方法の詳細に少し時間を費やしました。ブログにサンプル コードを含む完全な記事があります。より多くの議論と、サンプル プロジェクトの処理方法の説明が含まれているので、チェックしてみてください。これはおそらく完全または完全な解決策ではありませんが、非常に単純なスクリプトを使用して、 Working on My Machine TMを作成しました。
このアプローチは、PowerShell エラーを報告するときに行と列の精度を提供し、Visual Studio で慣れ親しんだダブルクリックでファイルに移動する動作もサポートします。不足している場合は、ニーズに合わせて拡張できると確信しています。また、Visual Studio のバージョンによっては、アセンブリ参照バージョンなどの詳細を確認する必要がある場合があります。
まず、クラス ライブラリ プロジェクトでカスタム MSBuild タスクをビルドします。ライブラリは、MSBuild と PowerShell の統合のために次のアセンブリを参照する必要があります。(この例では PowerShell 2.0 が必要であることに注意してください。)
- Microsoft.Build.Framework (GAC)
- Microsoft.Build.Utilities.v3.5 (GAC)
- System.Management.Automation (C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0 から)
次のように、タスク クラスを作成し、プロパティを公開して PowerShell スクリプトへのパスを指定します。
using System.IO;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class PsBuildTask : Task
{
[Required]
public string ScriptPath { get; set; }
public override bool Execute()
{
// ...
}
}
メソッド内でExecute()
、PowerShell ランタイムを開始し、スクリプトを実行して、エラーを収集します。プロパティを使用しLog
てエラーをログに記録します。終了したら、実行空間を閉じ、スクリプトがエラーを記録しなかった場合は true を返します。
// create Powershell runspace
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
// create a pipeline and feed it the script text
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(". " + ScriptPath);
// execute the script and extract errors
pipeline.Invoke();
var errors = pipeline.Error;
// log an MSBuild error for each error.
foreach (PSObject error in errors.Read(errors.Count))
{
var invocationInfo = ((ErrorRecord)(error.BaseObject)).InvocationInfo;
Log.LogError(
"Script",
string.Empty,
string.Empty,
new FileInfo(ScriptPath).FullName,
invocationInfo.ScriptLineNumber,
invocationInfo.OffsetInLine,
0,
0,
error.ToString());
}
// close the runspace
runspace.Close();
return !Log.HasLoggedErrors;
以上です。このアセンブリがあれば、MSBuild タスクを使用するように別のプロジェクトを構成できます。
たとえば、C# ベースのクラス ライブラリ プロジェクト (.csproj) について考えてみます。ビルド後のイベントにタスクを統合するには、いくつかのことが必要です。
<Project>
まず、次のように .csproj ファイルのノードのすぐ内側にタスクを登録します。
<UsingTask TaskName="PsBuildTask"
AssemblyFile="..\Noc.PsBuild\bin\Debug\Noc.PsBuild.dll" />
名前空間は必須ではないように見えますが、TaskName はタスク クラスの名前にする必要があります。AssemblyFile
カスタム MSBuild タスク アセンブリへの絶対パス、または .csproj ファイルに対する相対パスです。GAC のアセンブリの場合は、AssemblyName
代わりに属性を使用できます。
登録すると、タスクはビルド前およびビルド後のイベント内で使用できます。<Project>
次のように、.csproj ファイルの要素内でビルド イベントを構成します。
<Target Name="AfterBuild">
<PsBuildTask ScriptPath=".\script.ps1" />
</Target>
以上です。Visual Studio がプロジェクトをコンパイルすると、カスタム アセンブリとタスク オブジェクトが読み込まれ、タスクが実行されます。パイプラインによって発生したエラーが取得され、報告されます。
