Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keeps colours from msbuild output?

When I run msbuild at the command line it shows pretty colours in the console.

However when I run it from C# with Process.Start, the output appears in black and white. How can I keep the colours?

var info = new ProcessStartInfo("msbuild")
{
    UseShellExecute = false,
    CreateNoWindow = true,
    RedirectStandardError = true,
    RedirectStandardOutput = true,            
};

using (var p = Process.Start(info) )
{
    p.ErrorDataReceived += (s, e) => Console.Error.WriteLine(e.Data);
    p.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
    p.BeginErrorReadLine();
    p.BeginOutputReadLine();
    p.WaitForExit();
}

Also, while we're here, does it matter than I run Process.Start before BeginOutputReadLine ? Will any output be lost?


Motivation, for those interested. A project I work on uses a custom build tool (re-inventing the wheel imho). It uses msbuild but behind convoluted layers of indirection (simplified model above). Msbuild's helpful colours are lost. I'd like to save them.

like image 365
Colonel Panic Avatar asked Jul 05 '13 16:07

Colonel Panic


3 Answers

   p.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);

Process.OutputDataReceived reads text, not colors. The output redirection feature that's underneath this only redirect stdout text, not the console color attributes. You get the exact same thing when you run msbuild with the > redirect operator from the command line to send its output to a text file. You'll of course see bland text when you open the text file in Notepad.

Parsing the redirected output to re-color your own output is drastically impractical. You are stuck with bland. Then again, programmers don't complain often about the look-and-feel of the Error List window in the IDE :)

like image 115
Hans Passant Avatar answered Nov 05 '22 06:11

Hans Passant


Thats it, there is no other way to do it. Your code first starts the process and then appends the eventhandler. So there will be maybe some data that are lost, but that depends on how fast the cpu processes the code. You should better append the eventhandler first and then start the process. (see below)

using (var p = new Process())
{
    p.StartInfo = new ProcessStartInfo("msbuild")
    {
        UseShellExecute = false,
        CreateNoWindow = true,
        RedirectStandardError = true,
        RedirectStandardOutput = true,
    };
    p.ErrorDataReceived += (s, e) => ErrorLine(e.Data);
    p.OutputDataReceived += (s, e) => OutputLine(e.Data);
    p.BeginErrorReadLine();
    p.BeginOutputReadLine();
    p.Start();
    p.WaitForExit();
}
void ErrorLine(string text)
{
    Console.ForegroundColor = ConsoleColor.White;
    Console.BackgroundColor = ConsoleColor.DarkRed;
    Console.Error.WriteLine(text);
    Console.ResetColor();
}
void OutputLine(string text)
{
    Console.Error.WriteLine(text);
}
like image 25
Steven Spyrka Avatar answered Nov 05 '22 05:11

Steven Spyrka


I don't know about how can do this specifically for msbuild with all the warnings/errors/other things that do different colours, but you can change the console colour by using Console.ForegroundColor = ConsoleColor.Red; before you write to it, and reset it with Console.ResetColor();

So you would change ErrorDataRecieved subscription to do change the colour to red before you write, and reset the colour after you write the output.

like image 1
David Bennington Avatar answered Nov 05 '22 04:11

David Bennington