C#: get external shell command result line by line

戏子无情 提交于 2021-02-07 03:34:34

问题


I am writing a C# winform application that starts a second process to execute shell commands like "dir" and "ping". I redirect the second process's output so my app can receive the command result. It roughly works fine.

The only problem is my winform app receives the command line output as a whole instead of line by line. For example, it has to wait for the external "ping" command to finish (which takes many seconds or longer) and then receives the whole output (many lines) at once.

What I want is the app receives the cmdline output in real-time, i.e. by lines not by block. Is this doable?

I am using this code to read the output: while ((result = proc.StandardOutput.ReadLine()) != null)

But it does not work the way I expected. Thanks in advance.

EDIT: here is the code I am using:

    System.Diagnostics.ProcessStartInfo procStartInfo = new 
            System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);

    procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;

    // The following commands are needed to redirect the standard output.
    procStartInfo.RedirectStandardOutput = true;
    procStartInfo.UseShellExecute = false;
    procStartInfo.CreateNoWindow = true;
    // Now we create a process, assign its ProcessStartInfo and start it
    System.Diagnostics.Process proc = new System.Diagnostics.Process();
    proc.StartInfo = procStartInfo;
    proc.Start();

    // Get the output into a string
    string result;
    try {
        while ((result = proc.StandardOutput.ReadLine()) != null)
        {
            AppendRtfText(result+"\n", Brushes.Black);
        }
    } // here I expect it to update the text box line by line in real time
      // but it does not.

回答1:


Have a look at the example in this msdn article on how to do the reading completly async.

Beyond that I expect your code does to read line by line now but the UI doesn't get any time to repaint (missing Application.DoEvents(); after updating the RTFTextBox




回答2:


Instead of loop using while ((result = proc.StandardOutput.ReadLine()) != null) you should of using:

...
proc.OutputDataReceived += proc_DataReceived;
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit();

This will start asynchronous reading the lines when they arrives, you then handle the lines read by e.Data in proc_DataReceived handler, since you are use BeginOutputReadline the e.Data will be a string lines.




回答3:


This could be usefull:

http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/8d6cebfc-9b8b-4667-85b5-2b92105cd0b7/

http://www.dotnetperls.com/redirectstandardoutput




回答4:


I had the same issue and got around it with the following. I found that if I had an error in the external app I was getting no output at all using the ReadToEnd() method, so switched to use the line by line streamreader. Will be switching over to use the answer provided by Saa'd though as that looks like the proper way to handle it.

Also found this solution: c# coding convention public/private contexts which provides for error handling at the same time and giving a fuller explanation to the use of externalApp.OutputDataReceived += (sender, args) => Console.WriteLine(args.Data);

Process externalApp = new Process();
        externalApp.StartInfo.FileName = config.ExternalApps + @"\location\DeleteApp.exe";
        externalApp.StartInfo.Arguments = Directory.GetCurrentDirectory() + @"\..\..\..\project\argumentsForDeleteApp.xml";
        externalApp.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        externalApp.StartInfo.UseShellExecute = false;
        externalApp.StartInfo.RedirectStandardOutput = true;
        Console.Out.WriteLine(DateTime.UtcNow.ToLocalTime().ToString() +
            ":######    External app: " + externalApp.StartInfo.FileName + " -      START");
        externalApp.Start();
        using (StreamReader reader = externalApp.StandardOutput)
        {
            while (!reader.EndOfStream)
            {
                string result = reader.ReadLine();
                Console.Out.WriteLine(result);
            }
        }
        externalApp.WaitForExit();


来源:https://stackoverflow.com/questions/7121640/c-get-external-shell-command-result-line-by-line

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