可以在Project文件中指定MSBuild自定义Logger吗?

时间:2015-02-26 03:20:11

标签: logging build msbuild build-process

msbuild有一个命令行参数'/ logger',允许您在构建时指定自定义实现的记录器。 (https://msdn.microsoft.com/en-us/library/ms171471.aspx

  

msbuild.exe /?

     

...

     

/ logger:使用此记录器记录来自MSBuild的事件。要指定                      多个记录器,分别指定每个记录器。                      语法是:                        [,] [;]                      语法是:                        [。]                      语法是:                        {[,] | }                      是可选的,并通过                      完全按照您键入的方式记录到记录器。 (简称:/ l)                      例子:                        /logger:XMLLogger,MyLogger,Version=1.0.2,Culture=neutral                        /logger:XMLLogger,C:\Loggers\MyLogger.dll;OutputAsHTML

我想实现自己的自定义记录器。为了确保我的开发团队的其余部分在构建时随身携带;我想直接在项目文件中应用某种设置。

理想情况下,这意味着如果有人通过IDE,msbuild命令行构建项目和/或使用devenv命令行,则始终会运行自定义记录器。

在项目文件中可以使用哪些设置,属性或其他机制来设置自定义记录器?

2 个答案:

答案 0 :(得分:3)

答案是否定的。记录器是构建引擎的配置设置。您无法启动构建,然后配置构建引擎。以下是来自MSDN的代码片段 - 它显示了构建引擎初始化的正常流程:

// Instantiate a new Engine object
Engine engine = new Engine();

...

// Instantiate a new FileLogger to generate build log
FileLogger logger = new FileLogger();
// Register the logger with the engine
engine.RegisterLogger(logger);

// Build a project file
bool success = engine.BuildProjectFile(@"c:\temp\validate.proj");

//Unregister all loggers to close the log file
engine.UnregisterAllLoggers();

可能有办法破解它,因为每个MSBuild任务都会收到对构建引擎对象(IBuildEngine接口)的引用,您可以将其转换为Microsoft.BuildEngine.Engine并调用RegisterLogger方法。但请注意,这将是错误的,因为您将为构建中的所有项目全局修改引擎,并且它可能无法正常工作或停止工作。

答案 1 :(得分:1)

作为S.T.说:没有真正适当的方法来做到这一点。然而,通过相当简单的黑客攻击,即覆盖Build目标,您可以实现您想要的目标。不知道我是否会推荐它,覆盖这样的目标可能会破坏构建。

反正。我不喜欢在版本控制中存储程序集,所以让我们从自定义记录器的源代码开始,将它放在CustomLogger.cs文件中。自定义记录器将在运行中构建 - 但是如果您想要,您可以跳过此并直接使用程序集:

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace CustomLogger
{
  public class ScanLogger : Logger
  {
    public override void Initialize( IEventSource eventSource )
    {
      eventSource.MessageRaised += ( s, e ) =>
        System.Console.WriteLine( "HI THERE - " + e.Message );
    }
  }
}

然后在项目文件中,在导入Microsoft.CSharp.targets的行之后添加此

<PropertyGroup>
  <LoggerDll>Customlogger.dll</LoggerDll>
</PropertyGroup>

<Target Name="BuildCustomLoggerDll">
  <Csc Sources="$(MSBuildThisFileDirectory)customlogger.cs"
       References="System.dll;mscorlib.dll;Microsoft.Build.Framework.dll;Microsoft.Build.Utilities.v4.0.dll"
       TargetType="Library" OutputAssembly="$(MSBuildThisFileDirectory)$(LoggerDll)"/>
</Target>

<Target Name="ActualBuild"
        Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
        DependsOnTargets="$(BuildDependsOn)"
        Returns="$(TargetPath)"/>

<Target Name="Build">
  <Exec Command="C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe $(MSBuildThisFile) /t:ActualBuild /noconsolelogger /l:$(MSBuildThisFileDirectory)$(LoggerDll)"/>
</Target>

在未指定目标时在VS或命令行中构建时,将调用默认目标Build。这通常构建,但在这里我们覆盖它并使它做更有趣的事情:它将首先通过BuildCustomLoggerDll构建您的自定义记录器dll然后通过Exec任务手动调用msbuild并指定使用选择的customlogger 。构建的目标是ActualBuild,这是Build中找到的原始C:\Program Files (x86)\MSBuild\12.0\Bin\Microsoft.Common.CurrentVersion.targets目标的副本 - 所以这个示例适用于VS2013和C#项目,可能需要修改其他版本和其他语言。但它可以工作,并通过自定义记录器进行记录。