Udostępnij za pośrednictwem


Rejestratory kompilacji

Rejestratory umożliwiają dostosowywanie produkcji budowania i wyświetlać komunikaty, błędy lub ostrzeżenia w odpowiedzi na zdarzenia kompilacji szczególnych.Każdy rejestrator jest zaimplementowany jako.Klasa netto, który implementuje ILogger interfejs, który jest zdefiniowany w zestawie Microsoft.Build.Framework.dll.

Istnieją dwa podejścia, wykorzystywane podczas wdrażania rejestratora:

  • Wdrożenie ILogger interfejsu bezpośrednio.

  • Klasa dziedziczyć po klasie, Logger, który jest zdefiniowany w zestawie Microsoft.Build.Utilities.dll.Loggerimplementuje ILogger i zapewnia domyślne implementacje niektórych ILogger członków.

W tym temacie wyjaśnić, jak napisać proste rejestratora, który wynika z Logger, i wyświetla komunikaty konsoli, w odpowiedzi na pewne zdarzenia.

Rejestrowanie zdarzeń

Celem rejestratora jest zebranie informacji na temat postępu kompilacji, wykazanej przez silnik kompilacji, a następnie sprawozdanie informacji w wygodny sposób.Należy zastąpić wszystkie rejestratory Initialize metodę, która jest gdzie rejestratora rejestruje zdarzenia.W tym przykładzie rejestratora rejestry dla TargetStarted, ProjectStarted, i ProjectFinished zdarzenia.

public class MySimpleLogger : Logger
    {
        public override void Initialize(Microsoft.Build.Framework.IEventSource eventSource)
        {
            //Register for the ProjectStarted, TargetStarted, and ProjectFinished events
            eventSource.ProjectStarted += new ProjectStartedEventHandler(eventSource_ProjectStarted);
            eventSource.TargetStarted += new TargetStartedEventHandler(eventSource_TargetStarted);
            eventSource.ProjectFinished += new ProjectFinishedEventHandler(eventSource_ProjectFinished);
        }

Reagowanie na zdarzenia

Rejestratora jest zarejestrowany dla określonego zdarzenia, potrzebuje obsługi tych zdarzeń, kiedy występują one.Dla ProjectStarted, i ProjectFinished zdarzenia, rejestratora zapisuje po prostu krótką frazę i nazwę pliku projektu, zaangażowany w zdarzenie.W oknie konsoli są zapisywane wszystkie wiadomości z rejestratora.

void eventSource_ProjectStarted(object sender, ProjectStartedEventArgs e)
        {
            Console.WriteLine("Project Started: " + e.ProjectFile);         
        }

        void eventSource_ProjectFinished(object sender, ProjectFinishedEventArgs e)
        {
            Console.WriteLine("Project Finished: " + e.ProjectFile);
        }

Odpowiadać wartościom szczegółowości rejestratora

W niektórych przypadkach może być tylko Rejestruj informacje od zdarzenia, jeśli MSBuild.exe /verbosity przełącznika zawiera określoną wartość.W tym przykładzie TargetStarted obsługi zdarzeń rejestruje tylko wiadomości Jeśli Verbosity właściwość, która jest ustawiana przez /verbosity przełącznika, jest równa LoggerVerbosityDetailed.

void eventSource_TargetStarted(object sender, TargetStartedEventArgs e)
        {
            if (Verbosity == LoggerVerbosity.Detailed)
            {
                Console.WriteLine("Target Started: " + e.TargetName);
            }
        }

Określanie rejestratora

Po rejestratora jest skompilowany w zestawie, musisz powiedzieć MSBuild używać tego rejestratora podczas kompilacji.Można to zrobić za pomocą /logger przełącznik z MSBuild.exe.Aby uzyskać więcej informacji na temat dostępnych parametrów MSBuild.exe, zobacz Informacje w wierszu polecenia programu MSBuild.

Następujące polecenie tworzy projekt MyProject.csproj i zastosowań klasy rejestratora zaimplementowane w SimpleLogger.dll./nologo Przełącznik ukrywa transparent i praw autorskich i /noconsolelogger przełącznik wyłącza domyślną MSBuild konsoli rejestratora.

MSBuild /nologo /noconsolelogger /logger:SimpleLogger.dll

Następujące polecenie buduje projektu z samym rejestratora, ale z Verbosity poziom Detailed.

MSBuild /nologo /noconsolelogger /logger:SimpleLogger.dll /verbosity:Detailed

Przykład

Opis

Poniższy przykład zawiera kompletny kod dla rejestratora.

Kod

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

namespace SimpleLogger
{

    public class MySimpleLogger : Logger
    {
        public override void Initialize(Microsoft.Build.Framework.IEventSource eventSource)
        {
            //Register for the ProjectStarted, TargetStarted, and ProjectFinished events
            eventSource.ProjectStarted += new ProjectStartedEventHandler(eventSource_ProjectStarted);
            eventSource.TargetStarted += new TargetStartedEventHandler(eventSource_TargetStarted);
            eventSource.ProjectFinished += new ProjectFinishedEventHandler(eventSource_ProjectFinished);
        }

        void eventSource_ProjectStarted(object sender, ProjectStartedEventArgs e)
        {
            Console.WriteLine("Project Started: " + e.ProjectFile);         
        }

        void eventSource_ProjectFinished(object sender, ProjectFinishedEventArgs e)
        {
            Console.WriteLine("Project Finished: " + e.ProjectFile);
        }
        void eventSource_TargetStarted(object sender, TargetStartedEventArgs e)
        {
            if (Verbosity == LoggerVerbosity.Detailed)
            {
                Console.WriteLine("Target Started: " + e.TargetName);
            }
        }
    }
}

Przykład

Opis

Poniższy przykład pokazuje, jak zaimplementować rejestratora, który zapisuje dziennika do pliku zamiast wyświetlania go w oknie konsoli.

Kod

using System;
using System.IO;
using System.Security;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace MyLoggers
{
    // This logger will derive from the Microsoft.Build.Utilities.Logger class, 
    // which provides it with getters and setters for Verbosity and Parameters, 
    // and a default empty Shutdown() implementation. 
    public class BasicFileLogger : Logger
    {
        /// <summary> 
        /// Initialize is guaranteed to be called by MSBuild at the start of the build 
        /// before any events are raised. 
        /// </summary> 
        public override void Initialize(IEventSource eventSource)
        {
            // The name of the log file should be passed as the first item in the 
            // "parameters" specification in the /logger switch.  It is required
            // to pass a log file to this logger. Other loggers may have zero or more than  
            // one parameters. 
            if (null == Parameters)
            {
                throw new LoggerException("Log file was not set.");
            }
            string[] parameters = Parameters.Split(';');
            
            string logFile = parameters[0];
            if (String.IsNullOrEmpty(logFile))
            {
                throw new LoggerException("Log file was not set.");
            }
            
            if (parameters.Length > 1)
            {
                throw new LoggerException("Too many parameters passed.");
            }
            
            try
            {
                // Open the file 
                this.streamWriter = new StreamWriter(logFile);
            }
            catch (Exception ex)
            {
                if
                (
                    ex is UnauthorizedAccessException
                    || ex is ArgumentNullException
                    || ex is PathTooLongException
                    || ex is DirectoryNotFoundException
                    || ex is NotSupportedException
                    || ex is ArgumentException
                    || ex is SecurityException
                    || ex is IOException
                )
                {
                    throw new LoggerException("Failed to create log file: " + ex.Message);
                }
                else
                {
                    // Unexpected failure 
                    throw;
                }
            }

            // For brevity, we'll only register for certain event types. Loggers can also 
            // register to handle TargetStarted/Finished and other events.
            eventSource.ProjectStarted += new ProjectStartedEventHandler(eventSource_ProjectStarted);
            eventSource.TaskStarted += new TaskStartedEventHandler(eventSource_TaskStarted);
            eventSource.MessageRaised += new BuildMessageEventHandler(eventSource_MessageRaised);
            eventSource.WarningRaised += new BuildWarningEventHandler(eventSource_WarningRaised);
            eventSource.ErrorRaised += new BuildErrorEventHandler(eventSource_ErrorRaised);
            eventSource.ProjectFinished += new ProjectFinishedEventHandler(eventSource_ProjectFinished);
        }

        void eventSource_ErrorRaised(object sender, BuildErrorEventArgs e)
        {
            // BuildErrorEventArgs adds LineNumber, ColumnNumber, File, amongst other parameters 
            string line = String.Format(": ERROR {0}({1},{2}): ", e.File, e.LineNumber, e.ColumnNumber);
            WriteLineWithSenderAndMessage(line, e);
        }
        
        void eventSource_WarningRaised(object sender, BuildWarningEventArgs e)
        {
            // BuildWarningEventArgs adds LineNumber, ColumnNumber, File, amongst other parameters 
            string line = String.Format(": Warning {0}({1},{2}): ", e.File, e.LineNumber, e.ColumnNumber);
            WriteLineWithSenderAndMessage(line, e);
        }

        void eventSource_MessageRaised(object sender, BuildMessageEventArgs e)
        {
            // BuildMessageEventArgs adds Importance to BuildEventArgs 
            // Let's take account of the verbosity setting we've been passed in deciding whether to log the message 
            if ((e.Importance == MessageImportance.High && IsVerbosityAtLeast(LoggerVerbosity.Minimal))
                || (e.Importance == MessageImportance.Normal && IsVerbosityAtLeast(LoggerVerbosity.Normal))
                || (e.Importance == MessageImportance.Low && IsVerbosityAtLeast(LoggerVerbosity.Detailed))              
                )
            {
                WriteLineWithSenderAndMessage(String.Empty, e);
            }
        }

        void eventSource_TaskStarted(object sender, TaskStartedEventArgs e)
        {
            // TaskStartedEventArgs adds ProjectFile, TaskFile, TaskName 
            // To keep this log clean, this logger will ignore these events.
        }
        
        void eventSource_ProjectStarted(object sender, ProjectStartedEventArgs e)
        {
            // ProjectStartedEventArgs adds ProjectFile, TargetNames 
            // Just the regular message string is good enough here, so just display that.
            WriteLine(String.Empty, e);
            indent++;
        }

        void eventSource_ProjectFinished(object sender, ProjectFinishedEventArgs e)
        {
            // The regular message string is good enough here too.
            indent--;
            WriteLine(String.Empty, e);
        }
        
        /// <summary> 
        /// Write a line to the log, adding the SenderName and Message 
        /// (these parameters are on all MSBuild event argument objects) 
        /// </summary> 
        private void WriteLineWithSenderAndMessage(string line, BuildEventArgs e)
        {
            if (0 == String.Compare(e.SenderName, "MSBuild", true /*ignore case*/))
            {
                // Well, if the sender name is MSBuild, let's leave it out for prettiness
                WriteLine(line, e);
            }
            else
            {
                WriteLine(e.SenderName + ": " + line, e);
            }
        }
        
        /// <summary> 
        /// Just write a line to the log 
        /// </summary> 
        private void WriteLine(string line, BuildEventArgs e)
        {
            for (int i = indent; i > 0; i--)
            {
                streamWriter.Write("\t");
            }
            streamWriter.WriteLine(line + e.Message);
        }
        
        /// <summary> 
        /// Shutdown() is guaranteed to be called by MSBuild at the end of the build, after all  
        /// events have been raised. 
        /// </summary> 
        public override void Shutdown()
        {
            // Done logging, let go of the file
            streamWriter.Close();
        }

        private StreamWriter streamWriter;
        private int indent;
    }
}

Zobacz też

Koncepcje

Uzyskiwanie dzienników kompilacji za pomocą narzędzia MSBuild

Inne zasoby

Pojęcia dotyczące programu MSBuild