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:
- Why System.Console writes aren't automatically sent to Log of BuildSystem?
- Is inheriting from TextWriter and setting the streams of Console - a good solution for this problem?
- Perhaps someone already did this work and wrote a TextWriter implementation for sending output/error to the开发者_C百科 msbuild log?
- If not, where can I find some reference code that gives an example of a class that implements TextWriter?
Thanks.
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
One option could be to have a wrapper task, inheriting from ToolTask, which just invokes this external tool, stdout/stderr messages would get logged correctly. You could even override LogEventsFromTextOutput and correctly match and log errors and warnings, which would show up in VS. Eg. LC.cs
精彩评论