如果使用ContinueOnError=true,如何检查MSBuild任务是否失败

如果使用ContinueOnError=true,如何检查MSBuild任务是否失败,msbuild,msbuild-task,msbuild-4.0,Msbuild,Msbuild Task,Msbuild 4.0,我正在以ContinueOnError=true运行MSBuild任务: 所以我的构建总是成功的 有没有办法找出是否发生错误 我找不到包含此信息的MSBuild任务的任何输出。 我知道的唯一方法是解析日志文件中的错误,但这似乎是一种解决方法 (我正在使用MSBuild 4.0) 这是对@Ilya最后一次反馈的回答 我使用反馈/回答是因为评论的长度和格式限制 日志的作用域为单个目标或更具体的任务 这确实是我在阅读您的评论时提出的第一个问题,其中建议使用日志。haslogedErrors:“日

我正在以ContinueOnError=true运行MSBuild任务:


所以我的构建总是成功的

有没有办法找出是否发生错误

我找不到包含此信息的MSBuild任务的任何输出。 我知道的唯一方法是解析日志文件中的错误,但这似乎是一种解决方法

(我正在使用MSBuild 4.0)


这是对@Ilya最后一次反馈的回答
我使用反馈/回答是因为评论的长度和格式限制

日志的作用域为单个目标或更具体的任务

这确实是我在阅读您的评论时提出的第一个问题,其中建议使用
日志。haslogedErrors
:“日志的范围是什么?
不幸的是,我找不到合适的文档。MSND没有多大帮助…
为什么您知道它是针对任务的?
我对你的说法一点也不怀疑!我只是想知道某处是否有合适的文件。。 (我已经多年没有使用MSBuild;-)

在任何情况下,作为项目,您要构建什么

我的测试项目非常简单。
MyTest.project

如果生成MyTest.proj,
HasLoggedErrors
将设置为
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



一种方法是使用不同的目标生成self,例如,DefaultTargets one启动指向自身的自定义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

(此外,我目前维护的“真实”构建非常复杂,包含多个带有目标的项目文件……因此我无法将它们全部打包到单个项目文件中)。

或者编写自定义记录器并通过命令行传递它

那是我最后的希望!
我的“真实”构建有一个通过命令行传递的自定义记录器(为了简单起见,我没有在测试项目中使用它)。这实际上是生成日志(一个XML文件),我将对其进行解析,以确定是否记录了任何错误。
顺便说一句,我认为控制台记录器是一种“全局”记录器。
我错了吗

无论如何,自定义记录器也没有帮助,
Log.haslogedErrors
仍然设置为
false

是否有我不知道的方法引用特定记录器(例如我的自定义记录器)来询问它是否记录了任何错误?

它看起来确实像
Log
是针对单个目标的

嗯……如果buildengine实例上的反射是最后的手段,我仍然希望解析日志。
(别怪我!:-)


我的决定
经过一些调查,我决定坚持我最初的解决方案:解析日志以确定构建是否失败

查看我的评论,了解为什么我更喜欢这些,而不是迄今为止提供的建议

如果有人有其他想法,请毫不犹豫地分享:-)


(否则,我想这个问题就可以解决了…

您可以捕获并在之后检查它们是否存在错误条件,但这仍然是一个非常粗糙的问题。

如果您只想检查MSBuild任务是否失败,请使用task。将IgnoreExitCode设置为true并检查ExitCode输出值。如果不是零,就有问题了

如果需要生成错误列表,请使用仅将错误记录到某些特定文件:

/flp1:logfile=errors.txt;错误地

但是,如果某个目标内的另一个任务(例如Copytask)引发错误,Log.HasLoggedErrors将返回false

不知道评论有长度限制


日志的作用域是单个目标或更具体的任务,并且(据我所知)无法获得“全局”日志,可能是通过对buildengine实例的反射,或者编写自定义日志并通过命令行传递。在任何情况下,作为项目,您要构建什么?HasLoggedErrors按预期工作(多年来一直保持不变),它显示正在构建的项目是否记录了任何错误。它不应该也不应该对其他任务(可能使用其他类型的记录器)的日志记录进行任何控制。如果想要全局的,一种方法是使用不同的目标生成self,例如,DefaultTargets one启动指向自身的自定义MSBuildWrapper任务(即$(MSBuildProjectFile)),但使用执行其他生成、复制等的不同目标,理论上,它应该模拟一个全局HasLoggedErrors…

如果最后一个任务成功,
MSBuildLastTaskResult
将设置为
True
,如果最后一个任务失败,
False

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


我相信这是在MSBuild v4.0中引入的

我知道这个线程有点旧,但另一个可能的解决方案是使用:

<OnError ExecuteTargets="FinalReportTarget;CleanupTarget" />

如果出现错误,这将使构建失败,但执行“FinalReportTarget”和“CleanupTarget”


在这种情况下不需要ContinueOnError=“true”。

Hmm。。。如果没有更好的方法,我将更好地创建一个自定义任务,解析日志文件并计算错误(和警告)。使我的项目文件看起来更清晰@斯科利马
<MSBuild Projects="@(ComponentToDeploy)"
         Targets="$(DeploymentTargets)"
         Properties="$(CommonProperties);%(AdditionalProperties)"
         ContinueOnError="true" 
         Condition="%(Condition)" />
<Message Text="MSBuild failed!" Condition="'$(MSBuildLastTaskResult)' == 'False'" />
<OnError ExecuteTargets="FinalReportTarget;CleanupTarget" />