sto facendo funzionare il compito MSBuild con ContinueOnError = true:Come verificare se un MSBuild-Task non riesce se si utilizza ContinueOnError = true
<MSBuild Projects="@(ComponentToDeploy)"
Targets="$(DeploymentTargets)"
Properties="$(CommonProperties);%(AdditionalProperties)"
ContinueOnError="true"
Condition="%(Condition)"/>
Quindi la mia generazione riesce sempre.
C'è un modo per scoprire se si verifica un errore?
non ho trovato alcun uscita del compito MSBuild contenente queste informazioni. L'unico modo che conosco è analizzare il file di log per gli errori, ma sembra una soluzione alternativa per me.
(sto usando MSBuild 4,0)
Questa è una risposta all'ultima valutazioni di @Ilya.
Uso feedback/risposta a causa della lunghezza e delle restrizioni di formattazione dei commenti.
log è ambito di obiettivi individuali o per essere più specifici compiti ...
Questa è stata infatti la prima questione è stata sollevata quando stavo leggendo il tuo commento con il suggerimento di utilizzare Log.HasLoggedErrors
: "Era lo scopo del registro? ".
Purtroppo non ero in grado di trovare una documentazione adeguata. MSND non aiuta molto ...
Perché lo sapevate che è ambito per l'attività?
Non ho alcun dubbio sulla tua affermazione! Mi chiedo solo se c'è una documentazione adeguata da qualche parte .. (non sono stato utilizzando MSBuild per anni ;-)
In ogni caso, quello che stai costruendo come progetto ?
I miei progetti di test sono molto semplici.
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>
Il CopyNotExistingFile.proj cerca solo di copiare un file che non esiste:
<?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>
E questo è il mio compito personalizzato 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;
}
}
}
Se si crea il mio MyTest.proj il HasLoggedErrors
verrà impostato su false
sebbene sia stato registrato un errore (MSB3021) (?) Per il logger console:
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.
La mia aspettativa è stata HasLoggedErrors
verrebbe impostato su true
.
un modo è quello di costruire auto, ma con target diverso, per esempio il vostro DefaultTargets una lancia il vostro compito personalizzato MSBuildWrapper punta a se stesso (cioè $ (MSBuildProjectFile)), ma con un target diverso che altre build, copie
L'ho già provato (erano le mie indagini che intendevo nel mio post). Purtroppo non funziona nemmeno :-(
(mi rendo conto che hai detto in teoria) Il mio nuovo singolo progetto assomiglia a questo:.
<?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>
Se io costruisco questo progetto HasLoggedErrors
sarà ancora essere impostato su false
.
(Inoltre, la mia generazione "vero" attualmente sto mantenendo molto complexer contenente diversi file di progetto con gli obiettivi ... quindi non tutti in grado di confezionare in un unico file di progetto).
o scrivendo logger personalizzato e passando attraverso la linea di comando
Quella è stata la mia ultima speranza!
La mia build "reale" ha un logger personalizzato passato attraverso la riga di comando (non l'ho usato per il mio progetto di test per semplicità). Questo è in realtà la produzione del log (un file XML) che sto per analizzare per scoprire se sono stati registrati errori.
BTW, pensavo che il logger della console fosse una specie di registratore "globale". Mi sbaglio?
Ad ogni modo, il registratore personalizzato non è d'aiuto, lo Log.HasLoggedErrors
è ancora impostato su false
.
C'è un modo in cui non sono a conoscenza di fare riferimento a un particolare registratore (ad esempio il mio registratore personalizzato) per chiedere se ha registrato errori?
Sembra davvero che Log
abbia un ambito per i singoli target.
Hmm ... se il riflesso sull'istanza del buildengine è l'ultima risorsa, preferirei comunque analizzare il registro.
(Non prendetevela con me :-)!)
La mia decisione
Dopo alcune indagini ho deciso di restare con la mia soluzione iniziale: analizzare il registro per scoprire se la generazione non è riuscita .
Controlla i miei commenti per capire perché preferisco che i suggerimenti siano stati forniti finora.
Se qualcuno ha altre idee non esitano a condividere :-)
(In caso contrario, questa domanda può essere chiuso, immagino ...)
+1 per il suggerimento su una nuova proprietà riservata che ancora manca sul sito MSDN! Non ne ero consapevole. Questa è la soluzione che stavo cercando, grazie! – Elena
Se si esamina la parte inferiore della pagina Proprietà riservate MSDN, si vedrà che qualcuno della comunità ha documentato gentilmente diverse proprietà mancanti. Sconcertante che la documentazione ufficiale non sia mai stata aggiornata. –
Sì, ho letto questo commento proprio oggi e ho anche l'ultima edizione del libro di Sayed Ibrahim Hashimi sul mio tavolo ;-) ma non ero a conoscenza di questa proprietà, grazie ancora! – Elena