Jak sprawdzić, czy zadanie MSBuild nie powiedzie się, jeśli użyjesz ContinueOnError = true

UżywamMSBuild zadanie zContinueOnError= prawda:

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

Więc moja budowa zawsze się udaje.

Czy istnieje sposób, aby dowiedzieć się, czy wystąpił jakikolwiek błąd?

Nie mogłem znaleźć żadnegoWydajność zMSBuild zadanie zawierające tę informację. Jedynym sposobem, jaki znam, jest przeanalizowanie pliku dziennika pod kątem błędów, ale wygląda na to, że jest to dla mnie obejście.

(Używam MSBuild 4.0)

To jest odpowiedź na ostatnie opinie @Ilya.
Używam opinii / odpowiedzi ze względu na długość i ograniczenia formatowania komentarzy.

Dziennik jest ograniczony do indywidualnych celów lub do bardziej szczegółowych zadań ...

Było to rzeczywiście pierwsze pytanie, kiedy czytałem twój komentarz z sugestią użyciaLog.HasLoggedErrors: ”Czy był zakres dziennika?
Niestety nie udało mi się znaleźć odpowiedniej dokumentacji. MSND niewiele pomaga ...
Dlaczego wiesz, że jest to zakres zadania?
Nie mam wątpliwości co do twojego oświadczenia! Zastanawiam się tylko, czy jest gdzieś odpowiednia dokumentacja ... (nie używałemMSBuild przez lata ;-)

W każdym razie, co budujesz jako projekt?

Moje projekty testowe są bardzo proste.
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>

TheCopyNotExistingFile.proj po prostu próbuje skopiować plik, który nie istnieje:

<?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>

I to jest moje niestandardowe zadanieMSBuildWithHasLoggedErrors

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;
        }
    }
}

Jeśli zbuduję mój MyTest.proj theHasLoggedErrorszostanie ustawiony nafalse chociaż błąd (MSB3021) został zalogowany (?) do rejestratora konsoli:

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.

Moje oczekiwanie byłoHasLoggedErrors byłoby ustawione natrue.



jednym ze sposobów jest zbudowanie własnego ja, ale z innym celem, na przykład twoim DefaultTargets, który uruchamia twoje niestandardowe zadanie MSBuildWrapper wskazujące na siebie (tj. $ (MSBuildProjectFile)), ale z innym celem, który wykonuje inne kompilacje, kopie

Już to wypróbowałem (to były moje badania, które miałem na myśli w moim poście). Niestety to nie działa :-(
(Wiem, że powiedziałeśW teorii). Mój nowypojedynczy projekt wygląda tak:

<?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>

Jeśli zbuduję ten projektHasLoggedErrors nadal będzie ustawiony nafalse.
(Ponadto moja „prawdziwa” kompilacja, którą obecnie utrzymuję, jest znacznie bardziej złożona i zawiera kilka plików projektów z celami ... więc nie mogę ich spakować w jednym pliku projektu).

lub pisanie niestandardowego rejestratora i przekazywanie go za pomocą wiersza poleceń

To była moja ostatnia nadzieja!
Moja „prawdziwa” kompilacjama niestandardowy rejestrator przeszedł przez linię poleceń (dla uproszczenia nie użyłem go do mojego projektu testowego). To właśnie tworzy dziennik (plik XML) Zamierzam przeanalizować, aby dowiedzieć się, czy zostały zarejestrowane jakieś błędy.
Przy okazji pomyślałem, że logger konsoli jest rodzajem „globalnego” rejestratora. Czy się mylę?

W każdym razie niestandardowy rejestrator nie pomagaLog.HasLoggedErrors jest nadal ustawiony nafalse.
Czy jest jakiś sposób, którego nie znam, aby odwołać się do konkretnego rejestratora (np. Mojego niestandardowego programu rejestrującego), aby zapytać, czy zarejestrował jakieś błędy?

To naprawdę wyglądaLog jest ograniczony do indywidualnych celów.

Hmm ... jeśli odbicie na instancji buildengine jest ostatnią deską ratunku, nadal wolałbym analizować dziennik.
(Nie obwiniaj mnie! :-))

Moja decyzja
Po kilku badaniach postanowiłem trzymać się mojego początkowego rozwiązania: przeanalizować dziennik, aby dowiedzieć się, czy kompilacja nie powiodła się.

Sprawdź moje komentarze, aby zobaczyć, dlaczego wolę, aby sugestie były dotąd dostarczone.

Jeśli ktoś ma jakieś inne pomysły, nie wahaj się podzielić :-)

(W przeciwnym razie to pytanie może zostać zamknięte, jak przypuszczam ...)

questionAnswers(5)

yourAnswerToTheQuestion