2013-07-05 28 views
9

當我在命令行運行msbuild時,它在控制檯中顯示出漂亮的顏色。如何保持msbuild輸出的顏色?

但是,當我從C#運行它與Process.Start,輸出顯示爲黑色和白色。我怎樣才能保持顏色?

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(); 
} 

另外,雖然我們在這裏,它的問題比我BeginOutputReadLine之前運行Process.Start?任何輸出會丟失嗎?


對於那些感興趣的動機。我工作的一個項目使用定製構建工具(重新發明輪子imho)。它使用msbuild,但在間接的複雜層次之後(上面的簡化模型)。 Msbuild有用的顏色會丟失。我想保存它們。

+0

我看到你已經開了一個賞金不在乎告訴我們什麼方面對這個問題的根本漢斯帕桑特的回答不足以覆蓋?或者你是否開始賞金獎給他? –

+1

@CodyGray漢斯說這是不可能的。我希望它是可能的。 –

+0

不幸的是,他是對的。沒有辦法讓'OutputDataReceived'做到這一點。它輸出的全部是文本,而不是顏色。如果你想要顏色,你必須解析數據並手動應用它們,就像他說的。您可能對[VSColorOutput](http://visualstudiogallery.msdn.microsoft.com/f4d9c2b5-d6d7-4543-a7a5-2d7ebabc2496)擴展程序感興趣,該擴展程序會爲您執行此操作。 –

回答

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

Process.OutputDataReceived讀取文本,而不是顏色。輸出重定向功能僅在重定向標準輸出文本下面,而不是控制檯顏色屬性。當你從命令行運行帶有>重定向運算符的msbuild以將其輸出發送到文本文件時,你會得到完全相同的結果。當您在記事本中打開文本文件時,您當然會看到無聊的文字。

解析重定向的輸出以重新着色自己的輸出是非常不切實際的。你平淡無奇。然後再次,程序員不會經常抱怨IDE中的錯誤列表窗口的外觀和感覺:)

+0

認爲這可能是案件。 'RedirectStandardOutput = false'會發生什麼? –

+0

顯然,如果你不重定向輸出,那麼MSBuild會再次寫入控制檯。你不會看到任何東西,因爲你告訴它不創建控制檯。 –

1

我不知道如何做到這一點專門爲msbuild與所有的警告/錯誤/其他事情做不同的顏色,但你可以改變控制檯的顏色使用Console.ForegroundColor = ConsoleColor.Red;寫入之前,並重置它與Console.ResetColor();

因此,您將更改ErrorDataRecieved訂閱以在寫入之前將顏色更改爲紅色,並在寫入輸出後重置顏色。

4

就是這樣,沒有其他辦法可以做到這一點。 您的代碼首先啓動該過程,然後附加事件處理程序。因此,可能會丟失一些數據,但這取決於cpu處理代碼的速度。 您應該首先附加事件處理程序,然後啓動該過程。 (見下文)

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