Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging from msbuild Custom Task using Console class

I'm trying to convert an existing command line tool into msbuild custom task. This tool logs messages and errors using the System.Console class.
I've added to the tool's assembly a class that inherits from Microsoft.Build.Utilities.Task and calls the tool main function, and the custom tool works fine - but no messages/errors are displayed (on the Visual Studio output window).

I would like to avoid changing the original tool's code (otherwise I could change every "Console.Error.WriteLine" to "Log.LogError"). I thought of changing the stdout and stderr streams of console by calling Console.SetOut and SetError before calling the tool's main function. For that, I would need to implement a class that inherits from TextWriter.

So my questions are:

  1. Why System.Console writes aren't automatically sent to Log of BuildSystem?
  2. Is inheriting from TextWriter and setting the streams of Console - a good solution for this problem?
  3. Perhaps someone already did this work and wrote a TextWriter implementation for sending output/error to the msbuild log?
  4. If not, where can I find some reference code that gives an example of a class that implements TextWriter?

Thanks.

like image 302
Amir Gonnen Avatar asked Nov 05 '22 02:11

Amir Gonnen


1 Answers

Public Class TaskLogger
Inherits TextWriter

Public Enum TaskLoggerType
    out
    err
End Enum

Private m_logger As TaskLoggingHelper
Private m_logger_type As TaskLoggerType

Sub New(ByRef logger As TaskLoggingHelper, ByVal type As TaskLoggerType)
    m_logger = logger
    m_logger_type = type
End Sub

Public Overrides ReadOnly Property Encoding As System.Text.Encoding
    Get
        Return System.Text.Encoding.Default
    End Get
End Property

Public Overrides Sub WriteLine(ByVal value As String)
    Select Case m_logger_type
        Case TaskLoggerType.out
            m_logger.LogMessage(value)
        Case TaskLoggerType.err
            m_logger.LogError(value)
    End Select
End Sub
End Class

...

Public Overrides Function Execute() As Boolean
    Dim oldOut As TextWriter = Console.Out
    Dim oldErr As TextWriter = Console.Error
    Dim newOut As TextWriter = New TaskLogger(Log, TaskLogger.TaskLoggerType.out)
    Dim newErr As TextWriter = New TaskLogger(Log, TaskLogger.TaskLoggerType.err)
    Console.SetOut(newOut)
    Console.SetError(newErr)
    Dim result As Boolean = Run(...)
    Console.SetOut(oldOut)
    Console.SetOut(oldErr)
    Return result
End Function
like image 65
Amir Gonnen Avatar answered Nov 09 '22 13:11

Amir Gonnen