views:

134

answers:

1

Suppose I run msbuild like this:

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

In Posh console the output is in colors. That's pretty handy - you spot colors just by watching the output. And e.g. not important messages are grey.

Question

I'd like to add ability to redirect it somewhere like this (simplified example):

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
  • If I use 'Console', the cmdlet/function Redirect-AccordingToRedirectionVariable should output the msbuild messages with colors the same way as the output was not piped. In other words - it should leave the output as it is.
  • If I use 'TempFile', Redirect-AccordingToRedirectionVariable will store the output in a temp file.

Is it even possible? I guess it is not :| Or do you have any advice how to achieve the goal?

Possible solution:

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

But if you imagine there can be many many msbuild calls, it's not ideal.

Don't be shy to tell me any new suggestion how to cope with it ;)


Any background info about redirections/coloring/outpu is welcome as well.
(The problem is not msbuild specific, the problem touches any application that writes colored output)

+1  A: 

Yeah I would avoid piping colored output. At that point, AFAICT, all color info is lost. I would recommend using the /filelogger and /noconsolelogger parameters on MSBuild e.g.:

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 
    }
}

or you could do something even simpler like this:

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 
    }
}
Keith Hill
@Keith, thx for your answer. I'll definitely will use msbuild loggers. However, generally any application can output messages with colors, msbuild was only one of them.
stej
Yeah, I'm just not aware of any way to pipe either colored exe output or write-host -foregroundcolor output and not lose the color info.
Keith Hill