【问题标题】:Logging from msbuild Custom Task using Console class使用控制台类从 msbuild 自定义任务记录
【发布时间】:2011-02-28 12:12:30
【问题描述】:

我正在尝试将现有的命令行工具转换为 msbuild 自定义任务。 此工具使用 System.Console 类记录消息和错误。
我已将一个从 Microsoft.Build.Utilities.Task 继承并调用工具主函数的类添加到该工具的程序集中,并且自定义工具工作正常 - 但不显示任何消息/错误(在 Visual Studio 输出窗口上)。

我想避免更改原始工具的代码(否则我可以将每个“Console.Error.WriteLine”更改为“Log.LogError”)。 我想在调用工具的主要功能之前通过调用 Console.SetOut 和 SetError 来更改控制台的 stdout 和 stderr 流。为此,我需要实现一个继承自 TextWriter 的类。

所以我的问题是:

  1. 为什么 System.Console 不写入 自动发送到 Log of 构建系统?
  2. 继承自 TextWriter 并设置 Console 的流 - 好 这个问题的解决方案?
  3. 也许有人已经这样做了 工作并写了一个TextWriter 发送的实现 msbuild 日志的输出/错误?
  4. 如果没有,我在哪里可以找到一些 给出示例的参考代码 一个实现的类 文本编写器?

谢谢。

【问题讨论】:

    标签: .net vb.net visual-studio-2010 msbuild


    【解决方案1】:
    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
    

    【讨论】:

      【解决方案2】:

      一个选项可能是有一个包装任务,继承自 ToolTask​​,它只是调用这个外部工具,stdout/stderr 消息将被正确记录。您甚至可以覆盖 LogEventsFromTextOutput 并正确匹配并记录错误和警告,这将显示在 VS 中。例如。 LC.cs

      【讨论】:

      • 当您说“调用此外部工具”时,您是指启动一个新进程吗?我可以为此使用 Exec 任务而不是包装工具。我的目标是从 msbuild 中多次有效地调用该工具的 main 函数,而无需每次都启动新进程。
      • 是的,我就是这个意思。新工艺确实会很昂贵。我建议将 Console.Write* 调用更改为 Log 调用,让您更好地控制错误/警告/消息。例如,您可以使用 MessageImportance.Low 从您的工具记录调试消息,这不会污染常规输出,但在尝试调试错误时很有用。此外,更改控制台的 Out/Err 可能无法很好地与其他可能依赖它的事情一起执行,并行执行。
      • 在这种情况下,正如我在问题中提到的,我想避免更改原始工具的代码。但我想知道更改控制台的 Out/Err 是否会影响并行运行的其他事情......你确定吗?它不会只影响我进行更改的同一个程序集吗?
      • AFAICS,它应该会影响它正在执行的应用程序域。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-20
      • 1970-01-01
      • 1970-01-01
      • 2012-10-29
      相关资源
      最近更新 更多