Как проверить, если MSBuild-Task не удается при использовании ContinueOnError = true

Я бегуMSBuild задача сContinueOnError=true:

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

Так что моя сборка всегда удалась.

Есть ли способ узнать, происходит ли какая-либо ошибка?

Я не мог найти ни одногоOutput изMSBuild задание, содержащее эту информацию. Единственный способ, который я знаю, - это проанализировать файл журнала на наличие ошибок, но для меня это выглядит как обходной путь.

(Я использую MSBuild 4.0)

This is an answer to the last feedback of @Ilya.
I'm using feedback/answer because of the length and formatting restrictions of the comments.

Log is scoped to individual targets or to be more specific tasks...

Это был действительно первый вопрос, когда я читал ваш комментарий с предложением использоватьLog.HasLoggedErrors: & quot;Was is the scope of the Log?& Quot ;.
К сожалению, я не смог найти правильную документацию. MSND не сильно помогает ...
Почему вы знали, что это относится к задаче?
Я совсем не сомневаюсь в вашем утверждении! Мне просто интересно, есть ли где-нибудь надлежащая документация .. (Я не использовалMSBuild годами ;-)

In any case, what are you building as project?

Мои тестовые проекты очень просты.
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.projHasLoggedErrorsбудет установлен вfalse хотя ошибка (MSB3021) был зарегистрирован (?) в консоли журнала:

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.



one way is to build self but with different target, for example your DefaultTargets one launches your custom MSBuildWrapper task pointing to itself (ie $(MSBuildProjectFile)) but with a different target that does other builds, copies

Я уже пробовал это (это были мои исследования, которые я имел в виду в своем посте). К сожалению, это тоже не работает :-(
(Я знаю, что вы сказали,in theory). My new single Проект выглядит так:

<?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.
(Более того, моя «настоящая» сборка, которую я сейчас поддерживаю, намного сложнее, содержит несколько файлов проекта с целями ... поэтому я не могу упаковать их все в один файл проекта).

or writing custom logger and passing it through command line

Это была моя последняя надежда!
Мой "настоящий" строитьhas пользовательский регистратор прошел через командную строку (я не использовал его для моего тестового проекта ради простоты). Это на самом деле создает журнал (файл XML), который я собираюсь проанализировать, чтобы выяснить, не были ли зарегистрированы какие-либо ошибки.
BTW, I thought the console logger is a kind of "global" logger. Я ошибся?

Во всяком случае, пользовательский регистратор не помогает ни,Log.HasLoggedErrors все еще настроен наfalse.
Is there some way I am not aware of to reference a particular logger (e.g. my custom logger) to ask if it has logged any errors?

Это действительно выглядитLog относится к отдельным целям.

Хм ... если бы отражение в экземпляре builddengine было последним средством, я все равно предпочел бы разобрать бревно.
(Не вини меня! :-))

My decision
После некоторых исследований я решил придерживаться своего первоначального решения: проанализировать журнал, чтобы выяснить, не удалась ли сборка.

Проверьте мои комментарии, чтобы понять, почему я предпочитаю, чтобы предложения были предоставлены до сих пор.

Если у кого-то есть другие идеи, не стесняйтесь поделиться :-)

(Otherwise this question can be closed, I suppose...)

Ответы на вопрос(5)

Ваш ответ на вопрос