Me postulo la tareaMSBuild con ContinueOnError = true:¿Cómo comprobar si un MSBuild-tarea falla si se utiliza ContinueOnError = true
<MSBuild Projects="@(ComponentToDeploy)"
Targets="$(DeploymentTargets)"
Properties="$(CommonProperties);%(AdditionalProperties)"
ContinueOnError="true"
Condition="%(Condition)"/>
Así que mi construcción siempre tiene éxito.
¿Hay alguna manera de averiguar si ocurre algún error?
no pude encontrar ninguna salida del MSBuild tarea que contiene esta información. La única forma que conozco es analizar el archivo de registro en busca de errores, pero parece una solución para mí.
(estoy utilizando MSBuild 4,0)
Esta es una respuesta a la última votaciones de @Ilya.
Estoy usando comentarios/respuestas debido a la longitud y las restricciones de formato de los comentarios.
Log está en el ámbito de objetivos individuales o para ser más específicos ... tareas
Este fue de hecho la primera pregunta surgió cuando estaba leyendo su comentario con la sugerencia de utilizar Log.HasLoggedErrors
: "¿Fue el alcance del Log? ".
Desafortunadamente, no pude encontrar la documentación adecuada. MSND no ayuda mucho ...
¿Por qué sabía que tiene alcance para la tarea?
¡No tengo ninguna duda sobre su declaración! Me pregunto si hay una documentación adecuada en algún lugar .. (no he estado utilizando MSBuild durante años ;-)
En cualquier caso, lo que se construyen como proyecto ?
Mis proyectos de prueba son muy simples.
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>
El CopyNotExistingFile.proj simplemente intenta copiar un archivo que no existe:
<?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>
Y esta es mi tarea personalizada 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;
}
}
}
Si construyo mi MyTest.proj, el HasLoggedErrors
se establecerá en false
aunque se registró un error (MSB3021) (?) Al registrador de la consola:
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.
Mi expectativa era HasLoggedErrors
se establecería en true
.
una forma es construir uno mismo pero con diferente objetivo, por ejemplo sus DefaultTargets uno lanza su encargo tarea MSBuildWrapper apuntando a sí mismo (es decir, $ (MSBuildProjectFile)), pero con un objetivo diferente que otras construcciones, copias
Ya lo he intentado (esas fueron mis investigaciones que quise decir en mi publicación). Por desgracia, no funciona bien :-(
(Soy consciente de que dicho en teoría) Mi nuevo solo proyecto se parece a esto:.
<?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>
Si construyo este proyecto HasLoggedErrors
seguirá siendo establecerse en false
.
(Además, mi compilación "real" que actualmente mantengo es mucho más compleja y contiene varios archivos de proyecto con objetivos ... por lo que no puedo empaquetarlos todos en un solo archivo de proyecto)
o escribir registrador de costumbre y pasándolo a través de línea de comandos
Esa era mi última esperanza!
Mi construcción "real" tiene un registrador personalizado pasado a través de la línea de comandos (no lo usé para mi proyecto de prueba por simplicidad). Eso realmente está produciendo el registro (un archivo XML) que voy a analizar para averiguar si se han registrado errores.
Por cierto, pensé que el registrador de consola es una especie de registrador "global". ¿Estoy equivocado?
De todos modos, el registrador personalizado tampoco ayuda, el Log.HasLoggedErrors
todavía está configurado en false
.
¿Hay algún modo en el que no estoy consciente de hacer referencia a un registrador en particular (por ejemplo, mi registrador personalizado) para preguntar si ha registrado algún error?
Parece que Log
se ha adaptado a objetivos individuales.
Hmm ... si el reflejo en la instancia de buildengine es el último recurso, aún así preferiría analizar el registro.
(no me culpe :-)!)
Mi decisión
Después de algunas investigaciones que he decidido seguir con mi solución inicial: analizar el registro para averiguar si la compilación falló .
Revise mis comentarios para ver por qué prefiero que las sugerencias se hayan proporcionado hasta el momento.
Si alguien tiene algunas otras ideas no dudan en compartir :-)
(De lo contrario, esta pregunta puede ser cerrado, supongo ...)
+1 por la sugerencia de una nueva propiedad reservada que todavía falta en el sitio de MSDN. Yo no era consciente de ello. Esta es la solución que estaba buscando, ¡gracias! – Elena
Si mira la parte inferior de la página de propiedades reservadas de MSDN, verá que alguien de la comunidad documentó amablemente varias propiedades perdidas. Es desconcertante que la documentación oficial nunca haya sido actualizada. –
Sí, leí este comentario hoy e incluso tengo la última edición del libro de Sayed Ibrahim Hashimi en mi mesa ;-) pero no estaba al tanto de esta propiedad, ¡de nuevo! – Elena