Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MSBuild:如何获取引发的警告数?_Msbuild_Cruisecontrol.net - Fatal编程技术网

MSBuild:如何获取引发的警告数?

MSBuild:如何获取引发的警告数?,msbuild,cruisecontrol.net,Msbuild,Cruisecontrol.net,有一个MSBuild脚本,其中包括数字if Delphi和C#项目、单元测试等 问题是:如果发出警告(用于测试目的,而不是用于发布版本),如何标记生成失败?在自定义任务中使用LogError而不是LogWarning似乎不是一个好的选择,因为构建应该尽可能多地测试(直到出现真正的错误)以在一段时间内报告尽可能多的警告(构建项目在CruiseControl.NET中使用) 可能是,解决方案是创建我自己的记录器,将警告标志存储在其中,但我找不到是否有办法在构建结束时读取此标志 注意:在收到警告后立即

有一个MSBuild脚本,其中包括数字if Delphi和C#项目、单元测试等

问题是:如果发出警告(用于测试目的,而不是用于发布版本),如何标记生成失败?在自定义任务中使用LogError而不是LogWarning似乎不是一个好的选择,因为构建应该尽可能多地测试(直到出现真正的错误)以在一段时间内报告尽可能多的警告(构建项目在CruiseControl.NET中使用)

可能是,解决方案是创建我自己的记录器,将警告标志存储在其中,但我找不到是否有办法在构建结束时读取此标志

注意:在收到警告后立即使生成失败是没有问题的(Delphi编译器输出由自定义任务处理,并且/warnaError可用于C#),但是所需的行为是“生成所有内容;收集所有警告;使生成失败”,以报告所有警告,而不仅仅是第一个警告

p.p.S.至于我真的不需要警告的数量,而只需要它们存在的标志,我决定简化信号机制,使用简单的互斥,而不是共享内存。代码如下:

using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System.Threading;

namespace Intrahealth.Build.WarningLogger
{
    public sealed class WarningLoggerCheck : Task
    {
        public override bool Execute()
        {
            Log.LogMessage("WarningLoggerCheck:" + mutexName + "...");
            result = false;
            Mutex m = null;
            try
            {
                m = Mutex.OpenExisting(mutexName);
            }
            catch (WaitHandleCannotBeOpenedException)
            {
                result = true;
            }
            catch (Exception)
            {
            }

            if (result)
                Log.LogMessage("WarningLoggerCheck PASSED");
            else
                Log.LogError("Build log contains warnings. Build is FAILED");

            return result;
        }

        private bool result = true;
        [Output]
        public bool Result
        {
            get { return result; }
        }

        private string mutexName = "WarningLoggerMutex";
        public string MutexName
        {
            get { return mutexName; }
            set { mutexName = value ?? "WarningLoggerMutex"; }
        }
    }

    public class WarningLogger : Logger
    {
        internal static int warningsCount = 0;
        private string mutexName = String.Empty;
        private Mutex mutex = null;

        public override void Initialize(IEventSource eventSource)
        {
            eventSource.WarningRaised += new BuildWarningEventHandler(eventSource_WarningRaised);
        }

        private void SetMutex()
        {
            if (mutexName == String.Empty)
            {
                mutexName = "WarningLoggerMutex";
                if (this.Parameters != null && this.Parameters != String.Empty)
                {
                    mutexName = this.Parameters;
                }
            }

            mutex = new Mutex(false, mutexName);
        }

        void eventSource_WarningRaised(object sender, BuildWarningEventArgs e)
        {
            if (e.Message != null && e.Message.Contains("MSB3146"))
                return;
            if (e.Code != null && e.Code.Equals("MSB3146"))
                return;

            if (warningsCount == 0)
                SetMutex();
            warningsCount++;
        }
    }
}
C#编译器(csc.exe)有一个/warnaError开关,该开关将把警告视为错误并使生成失败。这也可以在.csproj文件中作为设置提供。我想德尔福也有类似的能力

msbuild.exe %~nx1 /t:Rebuild /p:Configuration=Release >> %MrB-BUILDLOG%
findstr /r /c:"[1-9][0-9]* Error(s)" >> %MrB-BUILDLOG%
if not errorlevel 1 (
   echo ERROR: sending notification email for build errors in '%~nx1'. >> %MrB-BUILDLOG%
) else (
   findstr /r /c:"[1-9][0-9]* Warning(s)" >> %MrB-BUILDLOG%
   if not errorlevel 1 (
       echo ERROR: sending notification email for build warnings in '%~nx1'. >>
%MrB构建日志% )否则( 回显成功生成的“%$nx1”。>>%MrB BUILDLOG% )
)

AFAIK MSBuild没有内置的支持,无法在生成脚本的给定点检索警告计数。但是,您可以按照以下步骤实现此目标:

  • 创建一个自定义记录器,用于侦听警告事件并统计警告数
  • 创建公开[Output]WarningCount属性的自定义任务
  • 自定义任务以某种方式从自定义记录器获取警告计数的值
  • 最困难的一步是第3步。为此,有几个选项,您可以在IPC-进程间通信下自由搜索它们。下面是一个如何实现这一点的工作示例。每个项都是不同的类库

    SharedMemory

    我已经为命名的 共享内存,它是 更大的项目。它基本上允许 序列化类型和对象图以 可以存储在共享中并从中检索 记忆(如你所料) 交叉过程)。是否更大 完成的项目是另一个 物质;-)

    采样记录器

    实现跟踪警告计数的自定义记录器

    namespace SampleLogger
    {
        using System;
        using Microsoft.Build.Utilities;
        using Microsoft.Build.Framework;
        using DM.SharedMemory;
    
        public class MySimpleLogger : Logger
        {
            private Segment s;
            private int warningCount;
    
            public override void Initialize(IEventSource eventSource)
            {
                eventSource.WarningRaised += new BuildWarningEventHandler(eventSource_WarningRaised);
    
                this.s = new Segment("MSBuildMetadata", SharedMemoryCreationFlag.Create, 65535);
                this.s.SetData(this.warningCount.ToString());
            }
    
            void eventSource_WarningRaised(object sender, BuildWarningEventArgs e)
            {
                this.warningCount++;
                this.s.SetData(this.warningCount.ToString());
            }
    
            public override void Shutdown()
            {
                this.s.Dispose();
                base.Shutdown();
            }
        }
    }
    
    采样任务

    实现读取MSbuild项目中引发的警告数的自定义任务。自定义任务从类库SampleLogger中实现的自定义记录器写入的共享内存中读取

    去兜风

    <?xml version="1.0" encoding="UTF-8"?>
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Main">
        <UsingTask TaskName="BuildMetadata" AssemblyFile="F:\temp\SampleLogger\bin\debug\SampleTasks.dll" />
    
        <Target Name="Main">
            <Warning Text="Sample warning #1" />
            <Warning Text="Sample warning #2" />
    
            <BuildMetadata>
                <Output
                    TaskParameter="WarningCount"
                    PropertyName="WarningCount" />
            </BuildMetadata>
    
            <Error Text="A total of $(WarningCount) warning(s) were raised." Condition="$(WarningCount) > 0" />
        </Target>
    </Project>
    
    这将是输出:

    Microsoft (R) Build Engine Version 2.0.50727.3053
    [Microsoft .NET Framework, Version 2.0.50727.3053]
    Copyright (C) Microsoft Corporation 2005. All rights reserved.
    
    Build started 30-09-2008 13:04:39.
    __________________________________________________
    Project "F:\temp\SampleLogger\bin\debug\test.xml" (default targets):
    
    Target Main:
        F:\temp\SampleLogger\bin\debug\test.xml : warning : Sample warning #1
        F:\temp\SampleLogger\bin\debug\test.xml : warning : Sample warning #2
        F:\temp\SampleLogger\bin\debug\test.xml(15,3): error : A total of 2 warning(s) were raised.
    Done building target "Main" in project "test.xml" -- FAILED.
    
    Done building project "test.xml" -- FAILED.
    
    Build FAILED.
    F:\temp\SampleLogger\bin\debug\test.xml : warning : Sample warning #1
    F:\temp\SampleLogger\bin\debug\test.xml : warning : Sample warning #2
    F:\temp\SampleLogger\bin\debug\test.xml(15,3): error : A total of 2 warning(s) were raised.
        2 Warning(s)
        1 Error(s)
    
    Time Elapsed 00:00:00.01
    

    很抱歉,但任务是收集所有警告(或者,至少,尽可能多地收集,直到出现真正的错误),然后将生成标记为失败。等待CruiseControl构建并不方便;接收第一次警告信息;修复此问题并等待下一个问题。对于想知道的人:Delphi 2009有一个将所有警告视为错误的方法您可以让msbuild忽略错误,但这样它就不会失败,并且所有生成都成功了。我喜欢这个建议。要点是:如果您遵循最佳实践并试图消除所有警告,那么在开始构建时就不应该有那么多警告。因此,“在将构建标记为失败之前收集所有警告”的想法似乎有些过分。我尝试使用几乎相同的方法,但在任务子类中使用静态成员来收集警告计数(但它不起作用)。谢谢你关于共享内存的想法。
    c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild test.xml /logger:SampleLogger.dll
    
    Microsoft (R) Build Engine Version 2.0.50727.3053
    [Microsoft .NET Framework, Version 2.0.50727.3053]
    Copyright (C) Microsoft Corporation 2005. All rights reserved.
    
    Build started 30-09-2008 13:04:39.
    __________________________________________________
    Project "F:\temp\SampleLogger\bin\debug\test.xml" (default targets):
    
    Target Main:
        F:\temp\SampleLogger\bin\debug\test.xml : warning : Sample warning #1
        F:\temp\SampleLogger\bin\debug\test.xml : warning : Sample warning #2
        F:\temp\SampleLogger\bin\debug\test.xml(15,3): error : A total of 2 warning(s) were raised.
    Done building target "Main" in project "test.xml" -- FAILED.
    
    Done building project "test.xml" -- FAILED.
    
    Build FAILED.
    F:\temp\SampleLogger\bin\debug\test.xml : warning : Sample warning #1
    F:\temp\SampleLogger\bin\debug\test.xml : warning : Sample warning #2
    F:\temp\SampleLogger\bin\debug\test.xml(15,3): error : A total of 2 warning(s) were raised.
        2 Warning(s)
        1 Error(s)
    
    Time Elapsed 00:00:00.01