16

コンパイル後にすべてのプラグインを正しい場所にプルし、ソリューションのマスタープロジェクトとの依存関係を整理するための、魔法のような巨大なジャンボを実行する、優れたPowerShell駆動のビルド後スクリプトがあります。

私の問題は、ときどき愚かなことをすると、スクリプトがその操作を正しく実行できない状態になり、PowerShellで何がうまくいかなかったかの詳細を示す例外をスローする可能性があることです。

これらの例外を取得してVisualStudioエラーウィンドウにプルアップし、ビルド後が失敗したときにvstudioが失敗通知を受け取り、他のすべての警告/エラーと一緒にウィンドウに適切にフォーマットする方法はありますか?

編集:これは私が理想的に探しているものの明確化です。

死んだImageShackリンクを削除しました

注:カスタムエラーメッセージをVisual Studioに表示する方法を探している場合(エラーメッセージを制御できる場合)、Roy Tinkerの回答を参照して、メッセージを表示するように調整する方法を学ぶことができます。制御できない予期しないエラーをキャッチすることに興味がある場合、またはより完全な解決策を見つけることに興味がある場合は、受け入れられた回答を参照してください。

4

2 に答える 2

19

[エラー一覧] ウィンドウに表示されるエラー、警告、またはメッセージを作成するには、ビルド前またはビルド後のイベントによって開始されたスクリプトから、次の形式でメッセージを stdout または stderr に記録するだけです。公式の仕様がある場合は、コメントまたは編集してください。これは、試行錯誤と MSBuild の出力を見て推測できたものにすぎません。角括弧は「オプション」を示します。

FilePath[(LineNumber[,ColumnNumber])]: MessageType[ MessageCode]: Description

例として:

E:\Projects\SampleProject\Program.cs(18,5): error CS1519: Invalid token '}' in class, struct, or interface member declaration

その他の例については、Visual Studio でビルドを実行したときに発生する可能性のあるエラー/警告/メッセージの [出力] ウィンドウを参照してください。

于 2013-01-04T21:32:19.760 に答える
13

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 がプロジェクトをコンパイルすると、カスタム アセンブリとタスク オブジェクトが読み込まれ、タスクが実行されます。パイプラインによって発生したエラーが取得され、報告されます。

スクリーンショット

于 2010-09-13T21:32:11.400 に答える