我正在使用ContinueOnError =true运行MSBuild任务:
<MSBuild Projects="@(ComponentToDeploy)"
Targets="$(DeploymentTargets)"
Properties="$(CommonProperties);%(AdditionalProperties)"
ContinueOnError="true"
Condition="%(Condition)"/>
所以我的构建总是成功的。
有没有办法找出是否发生任何错误?
我找不到包含此信息的MSBuild任务的任何输出。我知道的唯一方法是解析日志文件中的错误,但这对我来说似乎是一种解决方法。
(我正在使用 MSBuild 4.0)
这是对@Ilya 的最后反馈的回答。
由于评论的长度和格式限制,我正在使用反馈/答案。
日志的范围仅限于单个目标或更具体的任务......
当我阅读您的评论并建议使用以下内容时,这确实是第一个问题Log.HasLoggedErrors
:“日志的范围是多少? ”。
不幸的是,我找不到合适的文档。MSND 帮不上什么忙……
你为什么知道它是针对任务的?
我一点都不怀疑你的说法!我只是想知道某处是否有适当的文档..(我已经多年没有使用MSBuild了;-)
无论如何,您要构建什么项目?
我的测试项目非常简单。
我的测试项目
<?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
.
一种方法是构建 self 但具有不同的目标,例如,您的 DefaultTargets 启动指向自身的自定义 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.HasLoggedErrors
仍然设置为false
.
是否有某种我不知道的方法来引用特定记录器(例如我的自定义记录器)来询问它是否记录了任何错误?
它确实看起来像是Log
针对单个目标的。
嗯...如果对 buildengine 实例的反射是最后的手段,我仍然更喜欢解析日志。
(别怪我!:-))
我的决定
经过一番调查后,我决定坚持我最初的解决方案:解析日志以确定构建是否失败。
检查我的评论,看看为什么我更喜欢迄今为止提供的建议。
如果有人有其他想法,请不要犹豫分享:-)
(否则这个问题可以关闭,我想......)