Click here to Skip to main content
14,486,715 members
Rate this:
Please Sign up or sign in to vote.
See more:
I have a console application that is counting a percentage up, and it takes some time to finish.
I can call and read it's output inside a winapplication, but inside a single global variable, that gather everything while the console app is running, and AfteR all is finished, myvar will finally display its content. Practical, but Not Nice !
I want to see the console output updating live in my win app !
Thank you !

What I have tried:

       void ComandExecute()
        {
            //if (label1.InvokeRequired)  //I tried this but is getting skipped
            {

                string nl = "\r\n";
                string vvvh = "";

                Main.Text = "";
                var processInfo = new ProcessStartInfo("console_app.exe", "output> " + str1);
                processInfo.CreateNoWindow = true;
                processInfo.UseShellExecute = false;
                processInfo.RedirectStandardError = true;
                processInfo.RedirectStandardOutput = true;

                var process = Process.Start(processInfo);

//I tried here to obtain the output into my label but i get error01
//error01 says: 
//" Cross-thread operation not valid: Control 'label1' accessed from a thread other than the //thread it was created on. "

                process.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
                    {
                        label1.Text += e.Data + nl; label1.Refresh(); //<< error at this line
                    };
                process.BeginOutputReadLine();


                process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) =>
                vvvh += "error>>" + e.Data + nl;
                label1.Text += vvvh; label1.Refresh();
                process.BeginErrorReadLine();


                process.WaitForExit();
                vvvh += "ExitCode: " + process.ExitCode + nl;
                process.Close();

                Main.Text = vvvh;
                label1.Text = Main.Text;
            }
        }
Posted
Updated 4 days ago
Rate this:
Please Sign up or sign in to vote.

Solution 1

First off, add your handlers before you call Start on the process - or otherwise, you will lose any data the app generates before you add the handlers.

Second, the DataReceived events are always handled on a separate thread unless you set the Process.SynchronizingObject Property (System.Diagnostics) | Microsoft Docs[^] which synchronises data onto the UI thread for you.

Be aware that the OutputDataReceived event only works in complete lines.
   
Comments
_Q12_ 4 days ago
   
I dont know what handler is.
The program is working fine if i leave myvar to collect the data instead of my little intervention with the label on that line. But it does it all at once and then show the result.
Dave Kreskowiak 4 days ago
   
event handlers.... those lines that mention "+= (object sender, ...)" are setting up event handlers.

You didn't really write this code, did you? Copy and paste?
_Q12_ 4 days ago
   
yes, i copy and paste most of it.
I'm getting some results, but not the ones i really want.
Thank you for all your kind help and understanding so far !
_Q12_ 4 days ago
   
@ Dave Kreskowiak, Im used to call them simply "events". Im not used to call them "handlers" but now i get it they have 3 names for the same thing: "event", "handler" and "event handler". I was aware of them named like that but really using only 1 naming. Thanks for clarification.
OriginalGriff 4 days ago
   
The "Event" is the thing you handle; The "handler" or "event Handler" is the code that runs when the Event occurs.
TextBox.TextChanged is an Event: your code that checks what the user typed is the Handler.
_Q12_ 4 days ago
   
Thank you !
Actually, this is VERY good explanation.
I've always thought the code inside event is just "code executed", but now it gets light, its "event handler|handled".
_Q12_ 4 days ago
   
I'm already testing mister OriginalGriff code from the link he suggested.
_Q12_ 4 days ago
   
I've tried your code and I still get full text, instead of line by line, updating, on the fly as I want it.
void ComandExecute()
{
using (Process process = new Process())
{
ProcessStartInfo processInfo = new ProcessStartInfo("console_app.exe", "-F " + str1);
process.StartInfo = processInfo;
//processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
//processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
process.Start();


// label1.Text = process.StandardOutput.BaseStream.EndRead(...something here...) ;
label1.Text = process.StandardOutput.ReadLine();
label1.Refresh();


process.Exited += new EventHandler(MyProcessExited);
process.EnableRaisingEvents = true;
process.SynchronizingObject = button1;
MessageBox.Show("Waiting for the process to exit....");


label1.Text = process.StandardOutput.ReadToEnd();
label1.Refresh();


process.WaitForExit();
}
}
Rate this:
Please Sign up or sign in to vote.

Solution 2

If you want the information in a Windows application then use a BackgroundWorker Class (System.ComponentModel) | Microsoft Docs[^] to do the calculations. That way you can get the value updated as it is being calculated.
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100