13

ContinueOnError =trueでMSBuildタスクを実行しています。

<MSBuild Projects="@(ComponentToDeploy)"
    Targets="$(DeploymentTargets)"
    Properties="$(CommonProperties);%(AdditionalProperties)"
    ContinueOnError="true" 
    Condition="%(Condition)"/>

したがって、私のビルドは常に成功します。

エラーが発生したかどうかを確認する方法はありますか?

この情報を含むMSBuildタスクの出力が見つかりませんでした。私が知っている唯一の方法は、エラーのログ ファイルを解析することですが、それは私にとっては回避策のようです。

(MSBuild 4.0 を使用しています)


これは、@Ilya の最後のフィードバックに対する回答です。
コメントの長さとフォーマットの制限のため、フィードバック/回答を使用しています。

ログの範囲は、個々のターゲットまたはより具体的なタスクに限定されます...

これは、使用するように提案されたあなたのコメントを読んでいたときに発生した最初の質問でしたLog.HasLoggedErrors:「ログの範囲はありましたか?」.
残念ながら、適切なドキュメントを見つけることができませんでした。MSND はあまり役に立ちません...
なぜそれがタスクに限定されていることを知っていたのですか?
私はあなたの発言にまったく疑いを持っていません!どこかに適切なドキュメントがあるかどうか疑問に思っています..(私は何年もMSBuildを使用していません;-)

いずれにしても、プロジェクトとして何を構築していますか?

私のテスト プロジェクトは非常に単純です。
MyTest.project

<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="ElenasTarget" ToolsVersion="4.0">

    <UsingTask AssemblyFile="$(MSBuildProjectDirectory)\MyCompany.Tools.MSBuild.Tasks.dll" TaskName="MSBuildWithHasLoggedErrors" />

    <ItemGroup>
        <MyProjects Include="CopyNotExistingFile.proj" />
    </ItemGroup>

    <Target Name="ElenasTarget">
        <MSBuildWithHasLoggedErrors Projects="@(MyProjects)" ContinueOnError="true" >
            <Output TaskParameter="HasLoggedErrors" PropertyName="BuildFailed" />
         </MSBuildWithHasLoggedErrors>

         <Message Text="BuildFailed=$(BuildFailed)" />
  </Target>
</Project>

CopyNotExistingFile.projは、存在しないファイルをコピーしようとします

<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Target1" ToolsVersion="4.0">
    <Target Name="Target1"> 
         <Copy SourceFiles="C:\lalala.bum" DestinationFiles="C:\tralala.bam" />
  </Target>
</Project>

そして、これは私のカスタム タスクMSBuildWithHasLoggedErrors です。

namespace MyCompany.Tools.MSBuild.Tasks
{
    public class MSBuildWithHasLoggedErrors : Microsoft.Build.Tasks.MSBuild
    {
        [Output]
        public bool HasLoggedErrors { get; private set; }

        public override bool Execute()
        {
            try
            {
                base.Execute();
                HasLoggedErrors = Log.HasLoggedErrors;
            }
            catch (Exception e)
            {
                Log.LogErrorFromException(e, true);
                return false;
            }

            return true;
        }
    }
}

MyTest.proj をビルドすると、エラー ( MSB3021 ) がコンソール ロガーに記録 (?) されましたが、次のHasLoggedErrorsように設定されます。false

Project "C:\Users\elena\mytest.proj" on node 1 (default targets).
Project "C:\Users\elena\mytest.proj" (1) is building "C:\Users\elena\CopyNotExistingFile.proj" (2) on node 1 (default targets).
Target1:
  Copying file from "C:\lalala.bum" to "C:\tralala.bam".
C:\Users\elena\CopyNotExistingFile.proj(5,4): error MSB3021: Unable to copy file "C:\lalala.bum" to "C:\tralala.bam". Could not find file 'C:\lalala.bum'.
Done Building Project "C:\Users\elena\CopyNotExistingFile.proj" (default targets) -- FAILED.
ElenasTarget:
  BuildFailed=False
Done Building Project "C:\Users\elena\mytest.proj" (default targets).

Build succeeded.

私の期待はHasLoggedErrorsに設定されていましたtrue



1 つの方法は、自分自身を異なるターゲットでビルドすることです。たとえば、DefaultTargets は、それ自体を指すカスタム MSBuildWrapper タスクを起動しますが (つまり、$(MSBuildProjectFile))、他のビルドを実行する別のターゲットを使用してコピーします。

私はすでにそれを試しました(それは私の投稿で意味した私の調査でした)。残念ながら、どちらも機能しません:- ((理論的
にはあなたが言ったことは承知しています)。私の新しい単一プロジェクトは次のようになります。

<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="ElenasTarget" ToolsVersion="4.0">

    <UsingTask AssemblyFile="$(MSBuildProjectDirectory)\MyCompany.Tools.MSBuild.Tasks.dll" TaskName="MSBuildWithHasLoggedErrors" />

    <Target Name="ElenasTarget">
        <MSBuildWithHasLoggedErrors Projects="$(MSBuildProjectFile)" Targets="CopyNotExistingFile" ContinueOnError="true" >
            <Output TaskParameter="HasLoggedErrors" PropertyName="BuildFailed" />
         </MSBuildWithHasLoggedErrors>

         <Message Text="BuildFailed=$(BuildFailed)" />
  </Target>

  <Target Name="CopyNotExistingFile" >
         <Copy SourceFiles="C:\lalala.bum" DestinationFiles="C:\tralala.bam" />
  </Target>
</Project>

このプロジェクトをビルドすると、HasLoggedErrorsまだ に設定されfalseます。
(さらに、私が現在維持している「実際の」ビルドは、ターゲットを含む複数のプロジェクト ファイルを含むはるかに複雑なため、それらすべてを 1 つのプロジェクト ファイルにまとめることはできません)。

またはカスタムロガーを作成してコマンドラインに渡す

それが私の最後の希望でした!
私の「実際の」ビルドには、コマンド ラインを介して渡されるカスタム ロガーがあります (簡単にするために、テスト プロジェクトでは使用しませんでした)。これで実際にログ (XML ファイル) が作成され、エラーがログに記録されているかどうかを確認するために解析します。
ところで、コンソールロガーは一種の「グローバル」ロガーだと思いました。私が間違っている?

とにかく、カスタムロガーも役に立たず、Log.HasLoggedErrorsはまだ に設定されていfalseます。
特定のロガー (カスタム ロガーなど) を参照して、エラーがログに記録されているかどうかを確認する方法はありますか?

Log個々のターゲットにスコープが設定されているように見えます。

うーん... buildengine インスタンスのリフレクションが最後の手段である場合でも、ログを解析することをお勧めします。
(私を責めないでください! :-) )


私の決定
いくつかの調査の後、最初の解決策に固執することにしました。ログを解析して、ビルドが失敗したかどうかを調べます。

私のコメントをチェックして、これまでに提供された提案よりもそれを好む理由を確認してください。

誰かが他のアイデアを持っている場合は、遠慮なく共有してください:-)

(そうでなければ、この質問は閉じることができると思います...)

4

5 に答える 5

23

最後のタスクが成功し、最後のタスクが失敗した場合、MSBuildLastTaskResult 予約済みプロパティは次のように設定されます。TrueFalse

<MSBuild Projects="@(ComponentToDeploy)"
         Targets="$(DeploymentTargets)"
         Properties="$(CommonProperties);%(AdditionalProperties)"
         ContinueOnError="true" 
         Condition="%(Condition)" />
<Message Text="MSBuild failed!" Condition="'$(MSBuildLastTaskResult)' == 'False'" />

これは MSBuild v4.0 で導入されたと思います。

于 2012-06-05T19:44:17.410 に答える
0

後でそれらをキャプチャTargetOutputsしてエラー状態をチェックすることもできますが、それでもかなりハックです。

于 2012-05-29T10:37:40.773 に答える
0

ただし、ターゲット内の別のタスク (Copytask など) でエラーが発生した場合、Log.HasLoggedErrors は false を返します。

コメントに長さ制限があることを知らなかった...

ログは個々のターゲットまたはより具体的なタスクにスコープされており、(私が知る限り)「グローバル」なものを取得する方法はありません。ビルドエンジン インスタンスでのリフレクション、またはカスタム ロガーの作成と渡しによる可能性があります。コマンドラインから。いずれにしても、プロジェクトとして何を構築していますか? HasLoggedErrors は期待どおりに動作し (そして何年も変更されずに動作しています)、ビルドされたプロジェクトがエラーをログに記録したかどうかを示します。他のタスク (他のタイプのロガーを使用する可能性があります) のロギングを制御することはできませんし、制御すべきではありません。グローバルなものが必要な場合、1 つの方法は、自分自身を異なるターゲットでビルドすることです。たとえば、DefaultTargets は、それ自体を指すカスタム MSBuildWrapper タスクを起動しますが (つまり、$(MSBuildProjectFile))、他のビルド、コピー、など、理論的にはグローバルな HasLoggedErrors をシミュレートする必要があります...

于 2012-05-30T19:34:33.993 に答える
0

MSBuild タスクが失敗したかどうかのみを確認する場合は、Execタスクを使用します。IgnoreExitCode を true に設定し、ExitCode の出力値を確認します。ゼロでない場合は、何かが間違っています。

ビルド エラーのリストが必要な場合は、/fileloggerparameters コマンド ライン スイッチを使用して、特定のファイルにのみエラーを記録します。

/flp1:logfile=errors.txt;エラーのみ

于 2012-05-29T12:32:08.353 に答える