Output redirection still with colors in PowerShell
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)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
}
}
精彩评论