[.net] C#: Launching another process and capturing stdout

Started by
4 comments, last by Headkaze 15 years, 2 months ago
Hey, I'm trying to use C# to make a GUI front-end for some C++ command-line apps I have, but my C# knowledge is next to none, so I'm trying to find some examples on the web that do what I need. I got everything working, I just can't capture the output and display it in real-time. In my test app, I produce about one line of text every second for 5 seconds. In every method I've seen, the C# app simply spits out all the text 5 seconds later. Does anyone know how I can capture the input in real-time and display it into a text-box? [Edited by - gekko on January 19, 2009 3:47:05 PM]
-- gekko
Advertisement
Console.OpenStandardOutput

StreamWriter.AutoFlush

Might be what you're looking for?
Rainweaver Framework (working title)

IronLua (looking for a DLR expert)



Unfortunately, no. I'm making a GUI wrapper in C#, and trying to launch a C++ console app, so I'm using System.Diagnostics.Process to do so.

        private void exportButton_Click(object sender, EventArgs e)        {            System.Diagnostics.Process p = new System.Diagnostics.Process();            p.StartInfo.FileName = "ModelExporter.exe";            p.StartInfo.Arguments = "";            p.StartInfo.RedirectStandardOutput = true;            p.StartInfo.RedirectStandardInput = true;            p.StartInfo.UseShellExecute = false;            p.StartInfo.CreateNoWindow = true;            p.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(ConsoleOutputHandler);                   p.Start();            p.BeginOutputReadLine();            //p.WaitForExit();            //p.Dispose();        }        private void UpdateTextBox(String message)        {            if (consoleOutputBox.InvokeRequired)            {                UpdateConsoleWindowDelegate update = new UpdateConsoleWindowDelegate(UpdateTextBox);                consoleOutputBox.BeginInvoke(update, message);            }            else            {                consoleOutputBox.AppendText(message);            }        }        void ConsoleOutputHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs recieved)        {            if (!String.IsNullOrEmpty(recieved.Data))            {                UpdateTextBox(recieved.Data + "\n");            }        }


As I said before, this is working for me, but it outputs all the captured output at once when the console app finishes. I want it to capture every time there is a write to the console from the C++ app, it captures it and updates the text box.
-- gekko
Quote:Original post by gekko
p.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(ConsoleOutputHandler);


Have you tried using the 'StandardOutput' property instead? I have had good results in the past using a method similar to the below:

System.Diagnostics.Process p = new System.Diagnostics.Process();p.StartInfo.FileName = "ModelExporter.exe";p.StartInfo.RedirectStandardOutput = true;p.StartInfo.RedirectStandardInput = true;p.StartInfo.UseShellExecute = false;p.StartInfo.CreateNoWindow = true;p.Start();StreamReader myStreamReader = p.StandardOutput;// Reads a single line of the programs output.string myString = myStreamReader.ReadLine(); // This would print the string to the DOS Console for the sake of an example.// You could easily set a textbox control to this string instead...Console.WriteLine(myString);p.Close();


For more information see:Process.StandardOutput Property.

-Bill
Thanks guys. Apparently, it was working the whole time. Running a console app with more output indeed updates in real-time, but my program outputting only limited amount of data at a slow rate, all got buffered into the same call.
-- gekko
You can make your C++ console app output in realtime by adding the following line to the C++ app

setvbuf( stdout, NULL, _IONBF, 0);

This topic is closed to new replies.

Advertisement