开发者

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜