Перенаправление вывода по-прежнему с цветами в PowerShell

Предположим, я запускаю msbuild следующим образом:

function Clean-Sln {
    param($sln)
    MSBuild.exe $sln /target:Clean
}
Clean-Sln c:\temp\SO.sln

В шикарной консоли вывод в цветах. Это очень удобно - вы выбираете цвета, просто наблюдая за результатами. И, например, не важные сообщения серого цвета.

Вопрос

Я хотел бы добавить возможность перенаправить его куда-нибудь так (упрощенный пример):

function Clean-Sln {
    param($sln)
    MSBuild.exe $sln /target:Clean | Redirect-AccordingToRedirectionVariable
}
$global:Redirection = 'Console'
Clean-Sln c:\temp\SO.sln
$global:Redirection = 'TempFile'
Clean-Sln c:\temp\Another.sln
  • Если я использую "Консоль", командлет / функция Redirect-AccordingToRedirectionVariable должен выводить сообщения msbuild с цветами так же, как вывод не был передан по конвейеру. Другими словами - он должен оставить вывод как есть.
  • Если я использую "TempFile", Redirect-AccordingToRedirectionVariable сохранит вывод во временном файле.

Это вообще возможно? Я думаю, это не так:| Или у вас есть какой-либо совет, как достичь цели?

Возможное решение:

if ($Redirection -eq 'Console) {
  MSBuild.exe $sln /target:Clean | Redirect-AccordingToRedirectionVariable
} else {
  MSBuild.exe $sln /target:Clean | Out-File c:\temp.txt  
}

Но если представить, что может быть много вызовов msbuild, это не идеально.

Не стесняйтесь сказать мне любое новое предложение, как справиться с этим;)


Любая справочная информация о перенаправлениях / раскрасках / выходах также приветствуется.
(Проблема не специфична для msbuild, проблема касается любого приложения, которое записывает цветной вывод)

1 ответ

Да, я бы не использовал цветной вывод. В этот момент, AFAICT, вся информация о цветах теряется. Я бы порекомендовал использовать параметры /filelogger и /noconsolelogger в MSBuild, например:

function Invoke-MSBuild($project, [string[]]$targets, [switch]$logToFile) {
    $OFS = ';'
    $targetArg = if ($targets) {"/t:$targets"} else {''}
    if ($logToFile) {
        msbuild.exe $project $targetArg  /filelogger /noconsolelogger
    }
    else {
        msbuild.exe $project $targetArg 
    }
}

или вы могли бы сделать что-то еще проще, как это:

function Invoke-MSBuild($project, [string[]]$targets, $logFile) {
    $OFS = ';'
    $targetArg = if ($targets) {"/t:$targets"} else {''}
    if ($logFile) {
        msbuild.exe $project $targetArg > $logFile
    }
    else {
        msbuild.exe $project $targetArg 
    }
}
Другие вопросы по тегам