2013-07-07 19 views
2

我想調用一個可執行文件(在我的情況下,這是PNGOUT.exe)並從stdout中獲取它的輸出。但事實證明這很棘手 - 應用程序使用某種控制字符來替換之前打印的輸出(進度顯示),而C#類愉快地記錄它們,當我想分析輸出字符串時,我會感到頭疼。 (它甚至過了一段時間我要弄清楚什麼是我的字符串發生)如何處理使用控制字符的控制檯應用程序的輸出?

我打電話可執行與下面的方法:

public static string RunPNGOut(string pngOutPath, string target) { 
    var process = new Process { 
     StartInfo = { 
     UseShellExecute = false, 
     RedirectStandardOutput = true, 
     CreateNoWindow = true, 
     FileName = pngOutPath, 
     Arguments = '"' + target + '"' 
     } 
    }; 
    process.Start(); 

    var result = process.StandardOutput.ReadToEnd(); 

    process.WaitForExit(); 

    return result; 
} 

我必須要麼使用捕捉文本的唯一最終狀態不同的方法在控制檯中,或者以某種方式擺脫result中的控制字符(不是簡單地刪除它們,而是「將它們應用」以實現最終外觀)。如何做呢?

+0

控制字符是否被轉義? (例如'\\ t'而不是'\ t')? – keyboardP

+0

如果我只是打印字符串,它看起來只是最終文本,所以我認爲不,它們不會被轉義。 –

+1

如果沒有逃脫,那麼Base64編碼也許?基本上你需要確定你的輸入的性質。 –

回答

1

很可能,輸出包含\ r,它只是將光標返回到當前行的開頭。如果這是真的,那麼你可以通過擦除當前行來相應地調整字符串。然而,這並不簡單 - 您還必須覆蓋上一行。我會研究一些代碼,看看我能否找到解決方案。

編輯:這是我想出的解決方案 - 這是輕微測試。輸出將在lines變量中,您可以單獨進行分析,也可以將它們合併爲一條線進行分析。

string rawOut = "Results:\r\n___ % done\r 10\r 20\r 30\r\nError!"; 
string[] lines = Regex.Split(rawOut, Environment.NewLine); 
for(int j=0; j<lines.Length; j++) 
{ 
    string line = lines[j]; 
    if (line.Contains('\r')) 
    { 
     string[] subLines = line.Split('\r'); 
     char[] mainLine = subLines[0].ToCharArray(); 
     for(int i=1; i<subLines.Length; i++) 
     { 
      string subLine = Regex.Replace(subLines[i], ".\x0008(.)", "$1"); 
      if (subLine.Length > mainLine.Length) mainLine = subLine.ToCharArray(); 
      else subLine.CopyTo(0, mainLine, 0, subLine.Length); 
     } 
     lines[j] = new String(mainLine); 
    } 
} 
+0

\ r是唯一可以導致此行爲的符號?然後它可能會更簡單一些... –

+0

它可能不是隻能*這個符號,可能會導致這種行爲,但它是迄今爲止最常見的。我已經添加了我的解決方案 - 它基本上遍歷每個「真正的」行,並根據需要進行更新。 –

+1

不要忘記'\ b',非常常見。 –

相關問題