2015-02-26 4 views
2

Существует аргумент командной строки '/ logger' для msbuild, который позволяет вам указать произвольный встроенный регистратор при создании. (https://msdn.microsoft.com/en-us/library/ms171471.aspx)Может ли пользовательский Logger MSBuild быть указан в файле проекта?

msbuild.exe /?

...

/логгер: Используйте этот регистратор для регистрации событий с MSBuild. Чтобы указать несколько регистраторов, укажите каждый регистратор отдельно. Синтаксис: [,] [;] Синтаксис: [.] Синтаксис: {[,] | } Опционально и передаются в регистратор точно так же, как вы их набрали. (Краткая форма:/л) Примеры: /logger:XMLLogger,MyLogger,Version=1.0.2,Culture=neutral /logger:XMLLogger,C:\Loggers\MyLogger.dll;OutputAsHTML

Я Я хотел бы реализовать собственный собственный логгер. Чтобы убедиться, что остальная часть моей команды разработчиков работает с ней всякий раз, когда они строят; Я хочу применить какую-то настройку непосредственно в файле проекта.

В идеале это означает, что если кто-то построил проект через IDE, командную строку msbuild и/или используя командную строку devenv, пользовательский логгер всегда будет запускаться.

Какую настройку, свойство или другой механизм можно использовать в файле проекта для установки пользовательского регистратора?

ответ

2

Ответ отрицательный. Регистраторы - это параметры конфигурации для механизма сборки. Вы не можете запустить сборку, а затем настроить механизм сборки. Вот фрагмент кода из 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. Однако имейте в виду, что это было бы неправильно, потому что вы будете модифицировать движок глобально для всех проектов в сборке, и это может не работать или перестать работать в любое время.

0

As 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> 

При построении внутри ВС или в командной строке, когда не указана цель, будет вызываться цель по умолчанию Build.Обычно это происходит, но здесь мы переопределяем его и делаем для него более интересные вещи: сначала создадим вашу собственную DLL-файл logger с помощью BuildCustomLoggerDll, затем вызовите msbuild вручную с помощью задачи Exec и укажите, какой именно пользователь может выбрать. Целевая цель - ActualBuild, и это копия исходной цели Build, найденная в C:\Program Files (x86)\MSBuild\12.0\Bin\Microsoft.Common.CurrentVersion.targets - так что этот пример, если для VS2013 и C# проектов и, возможно, нуждается в модификациях для других версий и других языков. Но он работает и регистрируется через пользовательский регистратор.