如果使用ContinueOnError = true,如何检查MSBuild-Task是否失败 [英] How to check if a MSBuild-Task fails if using ContinueOnError=true

查看:103
本文介绍了如果使用ContinueOnError = true,如何检查MSBuild-Task是否失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am running the MSBuild task with ContinueOnError=true:

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

所以我的构建总是成功的.

So my build always succeeds.

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

Is there a way to find out if any error occurs?

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

I could not find any Output of the MSBuild task containing this information. The only way I know is to parse the log file for errors but it looks like a workaround for me.

(我正在使用MSBuild 4.0)

(I am using MSBuild 4.0)

这是对@Ilya的最新反馈的答案.
由于评论的长度和格式限制,我使用反馈/答案.

日志的范围仅限于单个目标或更具体的任务...

Log is scoped to individual targets or to be more specific tasks...

当我阅读您的建议并使用Log.HasLoggedErrors的建议时,这确实是第一个问题:"日志的范围是吗?".
不幸的是,我找不到合适的文档. MSND并没有太大帮助...
为什么知道它是任务范围的?
我完全不怀疑您的发言!我只是想知道某个地方是否有适当的文档. (多年来我一直没有使用 MSBuild ;-)

This was indeed the first question arose when I was reading your comment with the suggestion to use Log.HasLoggedErrors: "Was is the scope of the Log?".
Unfortunately I was not be able to finde a proper documentation. MSND does not help much...
Why did you know it is scoped to the task?
I'm not in doubt about your statement at all! I'm just wondering if there is a proper documentation somewhere.. (I haven't been using MSBuild for years ;-)

无论如何,您要作为项目建设什么?

In any case, what are you building as project?

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

My test projects are very simple.
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>

CopyNotExistingFile.proj 只是尝试复制不存在的文件:

The CopyNotExistingFile.proj just tries to copy a file that does not exist:

<?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.proj,尽管已将错误( MSB3021 )记录到控制台记录器中,但HasLoggedErrors将被设置为false:

If I build my MyTest.proj the HasLoggedErrorswill be set to false although an error (MSB3021) was logged(?) to the console logger:

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.





一种方法是构建自己的对象,但使用不同的目标,例如,DefaultTargets将启动指向其自身的自定义MSBuildWrapper任务(即$(MSBuildProjectFile)),但目标对象执行其他构建,复制

one way is to build self but with different target, for example your DefaultTargets one launches your custom MSBuildWrapper task pointing to itself (ie $(MSBuildProjectFile)) but with a different target that does other builds, copies

我已经尝试过了(这是我在帖子中所说的调查).不幸的是,它也不起作用:-(
(我知道您说的是理论上的). 我的新单个项目如下所示:

I've already tried it (that were my investigations I meant in my post). Unfortunately it doesn't work either :-(
(I am aware you said in theory). My new single project looks like this:

<?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.
(此外,我目前正在维护的真实"构建要复杂得多,其中包含带有目标的多个项目文件...因此,我无法将它们全部打包在一个项目文件中).

If I build this project HasLoggedErrors will still be set to false.
(Furthermore, my "real" build I'm currently maintaining is much complexer containing several project files with targets... so I can't pack them all in a single project file ).

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

or writing custom logger and passing it through command line

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

That was my last hope!
My "real" build has a custom logger passed through the command line (I didn't use it for my test project for the sake of simplicity). That is actually producing the log (a XML file) I'm going to parse to find out if any errors have been logged.
BTW, I thought the console logger is a kind of "global" logger. Am I wrong?

无论如何,自定义记录器也无济于事,Log.HasLoggedErrors仍设置为false.
我是否有某种方式无法引用特定的记录器(例如,我的自定义记录器)来询问它是否记录了任何错误?

Anyway, the custom logger does not help neither, the Log.HasLoggedErrors is still set to false.
Is there some way I am not aware of to reference a particular logger (e.g. my custom logger) to ask if it has logged any errors?

看起来Log的作用范围仅限于各个目标.

It really looks like Log is scoped to individual targets.

嗯...如果对buildengine实例的反思是最后的选择,我还是希望解析日志.
(别怪我!:-))

Hmm... if the reflection on the buildengine instance is the last resort I would still prefer parsing the log.
(Don't blame me! :-) )

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

My decision
After some investigations I've decided to stick with my initial solution: parse the log to find out if the build failed.

检查我的评论,以了解为什么我喜欢到目前为止已提供的建议.

Check my comments to see why I prefer that to the suggestions have been provided so far.

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

If someone has some other ideas do not hesitate to share :-)

(否则,这个问题可以解决,我想...)

推荐答案

MSBuildLastTaskResult

The MSBuildLastTaskResult reserved property will be set to True if the last task succeeded and False if the last task failed:

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

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

I believe this was introduced with MSBuild v4.0.

这篇关于如果使用ContinueOnError = true,如何检查MSBuild-Task是否失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆