How to deal with output from console applications that use control characters?

南楼画角 提交于 2019-12-08 01:01:54

问题


I want to call an executable (in my case, this is PNGOUT.exe) and grab its output from stdout. But it turned out to be tricky - the application uses some sort of control characters to replace previously printed output (display of progress), and C# classes happily record them and when I want to analyze the output string, I get serious headache. (It even took a while for me to figure out what's happening with my string)

I'm calling executable with following method:

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

I need either use different method that captures only final state of text in console, or somehow get rid of control characters in result(not simply delete them, but "apply" them to string to achieve the final look). How can it be done?


回答1:


Most likely, the output contains \r, which simply returns the cursor to the beginning of the current line. If that's true, then you can adjust the string accordingly by erasing the current line. It's not simple, though - you have to also overwrite the previous line. I'll work on some code and see if I can arrive at a solution.

EDIT: Here's the solution I came up with - it's lightly tested. The output will be in the lines variable, which you can either analyze individually or join together to analyze as a single line.

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


来源:https://stackoverflow.com/questions/17513175/how-to-deal-with-output-from-console-applications-that-use-control-characters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!