Redirecting StandardOutput in realtime

V

vijaynats

Hi

I created a windows app to run a dos batch file (which takes around
5mins to complete and generates lots of output messages on the console
in the meantime)and i used RedirectStandardOuput to display the output
text in a textbox.

The problem is that till the batch file has not finished running i
don't get to see the output in the text box!!

How do we trap the output and display as and when its generated by the
called app? can we get a LIVE UPDATE of the output?

Attached is part of the code for completeness :-

Your help will be greatly appreciated.

Thanks

Vijay

--------- CODE FOLLOWS -------------

// Create Process and Execute
p = new Process();

// Set Start Info
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow=false;
p.StartInfo.RedirectStandardOutput = false;
p.StartInfo.FileName = cmd;
p.StartInfo.WorkingDirectory="C:\\xyz\\";
p.Start();

StreamReader myStreamReader = p.StandardOutput;
// Read the standard output of the spawned process.
while((output = myStreamReader.ReadLine())!=null)
{
this.txtOutput.Text += output + "\r\n";
}
p.Close();
 
I

Ignacio Machin \( .NET/ C# MVP \)

hi,

I would do several changes:

First of all I would run this in a worker thread ( I will assume this)



p.StartInfo.RedirectStandardOutput = true;

while((output = myStreamReader.ReadLine())!=null)
{
string[] args = new string[1];
string[0] = output;
this.txtOutput.Invoke( UpdateOutput, args );
}

void UpdateTXTBOX( string line)
{
this.txtbox.Text+=line;
}

these are the declarations

public delegate void EventString( string line);

public EventString UpdateOutput = new EventString ( UpdateTXTBOX);



With that it should work.
Also consider change from a Textbox to something else, the strings
operations may have a performance impact.


cheers,
 
V

vijaynats

Hi

I tried your code...created a thread to spawn the process - still the
same - The standard output of the spawned process is available only
after the process has finished execution.

Since the called batch file is run in a different process, i guess we
need some kind of Interprocess communication (IPC) to send the output
of the spawned process to the calling process (my C# windows app).

Something like this -
----------------------

My App Spawned Process (batch file)
------- ----------------------------
Create Process ----------------------> Process Created
.. some processing...
.. some processing...
.. some output...
Receive Notification <------------------Send output text to 'My App'
Display in window ..some processing..
.. some processing...
.. some output...
Receive Notification <------------------Send output text to 'My App'
Display in window ..some processing..
.. some processing...
.. some output...
Receive Notification <------------------Send output text to 'My App'
Display in window ..some processing..
..Process Exit
Display Completed

But right now its happenning like this -
----------------------------------------
My App Spawned Process (batch file)
------- ----------------------------
Create Process ----------------------> Process Created
.. some processing...
.. some processing...
.. some output...(buffered ??)
..some processing..
.. some processing...
.. some output...(buffered ??)
.. some processing...
.. some output...(buffered ??)
..some processing..
..Process Exit
Read the output<--------------------- Send output text to 'My App'
Display the output
Display Completed

It would be great if yuu could throw some light on the internal working
of Process.start and how the output is made available to the calling
process and in what sequence.

Thanks

Vijay


hi,

I would do several changes:

First of all I would run this in a worker thread ( I will assume this)



p.StartInfo.RedirectStandardOutput = true;

while((output = myStreamReader.ReadLine())!=null)
{
string[] args = new string[1];
string[0] = output;
this.txtOutput.Invoke( UpdateOutput, args );
}

void UpdateTXTBOX( string line)
{
this.txtbox.Text+=line;
}

these are the declarations

public delegate void EventString( string line);

public EventString UpdateOutput = new EventString ( UpdateTXTBOX);



With that it should work.
Also consider change from a Textbox to something else, the strings
operations may have a performance impact.


cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation


Hi

I created a windows app to run a dos batch file (which takes around
5mins to complete and generates lots of output messages on the console
in the meantime)and i used RedirectStandardOuput to display the output
text in a textbox.

The problem is that till the batch file has not finished running i
don't get to see the output in the text box!!

How do we trap the output and display as and when its generated by the
called app? can we get a LIVE UPDATE of the output?

Attached is part of the code for completeness :-

Your help will be greatly appreciated.

Thanks

Vijay

--------- CODE FOLLOWS -------------

// Create Process and Execute
p = new Process();

// Set Start Info
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow=false;
p.StartInfo.RedirectStandardOutput = false;
p.StartInfo.FileName = cmd;
p.StartInfo.WorkingDirectory="C:\\xyz\\";
p.Start();

StreamReader myStreamReader = p.StandardOutput;
// Read the standard output of the spawned process.
while((output = myStreamReader.ReadLine())!=null)
{
this.txtOutput.Text += output + "\r\n";
}
p.Close();
 
I

Ignacio Machin \( .NET/ C# MVP \)

hi,

no really, the ipc mechanism is the stream. it's created for you by the OS.

did you google for it?

I did and found these:
http://groups-beta.google.com/group...public.dotnet.*&rnum=3&hl=en#9ce3ca48761b3195

http://groups-beta.google.com/group...public.dotnet.*&rnum=2&hl=en#5acce4bc96070bb5

It seems that one possible problem is that the output may be buffered

maybe changing the size of the buffer, I have no clear idea of how to do
this though :(

cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation


Hi

I tried your code...created a thread to spawn the process - still the
same - The standard output of the spawned process is available only
after the process has finished execution.

Since the called batch file is run in a different process, i guess we
need some kind of Interprocess communication (IPC) to send the output
of the spawned process to the calling process (my C# windows app).

Something like this -
----------------------

My App Spawned Process (batch file)
------- ----------------------------
Create Process ----------------------> Process Created
.. some processing...
.. some processing...
.. some output...
Receive Notification <------------------Send output text to 'My App'
Display in window ..some processing..
.. some processing...
.. some output...
Receive Notification <------------------Send output text to 'My App'
Display in window ..some processing..
.. some processing...
.. some output...
Receive Notification <------------------Send output text to 'My App'
Display in window ..some processing..
..Process Exit
Display Completed

But right now its happenning like this -
----------------------------------------
My App Spawned Process (batch file)
------- ----------------------------
Create Process ----------------------> Process Created
.. some processing...
.. some processing...
.. some output...(buffered ??)
..some processing..
.. some processing...
.. some output...(buffered ??)
.. some processing...
.. some output...(buffered ??)
..some processing..
..Process Exit
Read the output<--------------------- Send output text to 'My App'
Display the output
Display Completed

It would be great if yuu could throw some light on the internal working
of Process.start and how the output is made available to the calling
process and in what sequence.

Thanks

Vijay


hi,

I would do several changes:

First of all I would run this in a worker thread ( I will assume this)



p.StartInfo.RedirectStandardOutput = true;

while((output = myStreamReader.ReadLine())!=null)
{
string[] args = new string[1];
string[0] = output;
this.txtOutput.Invoke( UpdateOutput, args );
}

void UpdateTXTBOX( string line)
{
this.txtbox.Text+=line;
}

these are the declarations

public delegate void EventString( string line);

public EventString UpdateOutput = new EventString ( UpdateTXTBOX);



With that it should work.
Also consider change from a Textbox to something else, the strings
operations may have a performance impact.


cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation


Hi

I created a windows app to run a dos batch file (which takes around
5mins to complete and generates lots of output messages on the console
in the meantime)and i used RedirectStandardOuput to display the output
text in a textbox.

The problem is that till the batch file has not finished running i
don't get to see the output in the text box!!

How do we trap the output and display as and when its generated by the
called app? can we get a LIVE UPDATE of the output?

Attached is part of the code for completeness :-

Your help will be greatly appreciated.

Thanks

Vijay

--------- CODE FOLLOWS -------------

// Create Process and Execute
p = new Process();

// Set Start Info
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow=false;
p.StartInfo.RedirectStandardOutput = false;
p.StartInfo.FileName = cmd;
p.StartInfo.WorkingDirectory="C:\\xyz\\";
p.Start();

StreamReader myStreamReader = p.StandardOutput;
// Read the standard output of the spawned process.
while((output = myStreamReader.ReadLine())!=null)
{
this.txtOutput.Text += output + "\r\n";
}
p.Close();
 
V

vijaynats

The problem was becoz the launched process was blocking the UI thread.
Finally i found a way using which it works -

As you mentioned earlier..we have to use one thread each to create the
process, read the stdout and the stderr. These links may prove useful
to those following this topic -]

http://www.codeproject.com/csharp/LaunchProcess.asp

http://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/default.aspx

Thanks a ton Ignacio!

Cheers!

Vijay


hi,

no really, the ipc mechanism is the stream. it's created for you by the OS.

did you google for it?

I did and found these:
http://groups-beta.google.com/group...public.dotnet.*&rnum=3&hl=en#9ce3ca48761b3195

http://groups-beta.google.com/group...public.dotnet.*&rnum=2&hl=en#5acce4bc96070bb5

It seems that one possible problem is that the output may be buffered

maybe changing the size of the buffer, I have no clear idea of how to do
this though :(

cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation


Hi

I tried your code...created a thread to spawn the process - still the
same - The standard output of the spawned process is available only
after the process has finished execution.

Since the called batch file is run in a different process, i guess we
need some kind of Interprocess communication (IPC) to send the output
of the spawned process to the calling process (my C# windows app).

Something like this -
----------------------

My App Spawned Process (batch file)
------- ----------------------------
Create Process ----------------------> Process Created
.. some processing...
.. some processing...
.. some output...
Receive Notification <------------------Send output text to 'My App'
Display in window ..some processing..
.. some processing...
.. some output...
Receive Notification <------------------Send output text to 'My App'
Display in window ..some processing..
.. some processing...
.. some output...
Receive Notification <------------------Send output text to 'My App'
Display in window ..some processing..
..Process Exit
Display Completed

But right now its happenning like this -
----------------------------------------
My App Spawned Process (batch file)
------- ----------------------------
Create Process ----------------------> Process Created
.. some processing...
.. some processing...
.. some output...(buffered ??)
..some processing..
.. some processing...
.. some output...(buffered ??)
.. some processing...
.. some output...(buffered ??)
..some processing..
..Process Exit
Read the output<--------------------- Send output text to 'My App'
Display the output
Display Completed

It would be great if yuu could throw some light on the internal working
of Process.start and how the output is made available to the calling
process and in what sequence.

Thanks

Vijay


hi,

I would do several changes:

First of all I would run this in a worker thread ( I will assume this)



p.StartInfo.RedirectStandardOutput = true;

while((output = myStreamReader.ReadLine())!=null)
{
string[] args = new string[1];
string[0] = output;
this.txtOutput.Invoke( UpdateOutput, args );
}

void UpdateTXTBOX( string line)
{
this.txtbox.Text+=line;
}

these are the declarations

public delegate void EventString( string line);

public EventString UpdateOutput = new EventString ( UpdateTXTBOX);



With that it should work.
Also consider change from a Textbox to something else, the strings
operations may have a performance impact.


cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation


Hi

I created a windows app to run a dos batch file (which takes around
5mins to complete and generates lots of output messages on the console
in the meantime)and i used RedirectStandardOuput to display the output
text in a textbox.

The problem is that till the batch file has not finished running i
don't get to see the output in the text box!!

How do we trap the output and display as and when its generated by the
called app? can we get a LIVE UPDATE of the output?

Attached is part of the code for completeness :-

Your help will be greatly appreciated.

Thanks

Vijay

--------- CODE FOLLOWS -------------

// Create Process and Execute
p = new Process();

// Set Start Info
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow=false;
p.StartInfo.RedirectStandardOutput = false;
p.StartInfo.FileName = cmd;
p.StartInfo.WorkingDirectory="C:\\xyz\\";
p.Start();

StreamReader myStreamReader = p.StandardOutput;
// Read the standard output of the spawned process.
while((output = myStreamReader.ReadLine())!=null)
{
this.txtOutput.Text += output + "\r\n";
}
p.Close();
 
I

Ignacio Machin \( .NET/ C# MVP \)

hi,

Good to ear you solve your problem

Why don't you post some code, it may help another person and will be stored
in the archives :)

cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation


The problem was becoz the launched process was blocking the UI thread.
Finally i found a way using which it works -

As you mentioned earlier..we have to use one thread each to create the
process, read the stdout and the stderr. These links may prove useful
to those following this topic -]

http://www.codeproject.com/csharp/LaunchProcess.asp

http://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/default.aspx

Thanks a ton Ignacio!

Cheers!

Vijay


hi,

no really, the ipc mechanism is the stream. it's created for you by the
OS.

did you google for it?

I did and found these:
http://groups-beta.google.com/group...public.dotnet.*&rnum=3&hl=en#9ce3ca48761b3195

http://groups-beta.google.com/group...public.dotnet.*&rnum=2&hl=en#5acce4bc96070bb5

It seems that one possible problem is that the output may be buffered

maybe changing the size of the buffer, I have no clear idea of how to do
this though :(

cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation


Hi

I tried your code...created a thread to spawn the process - still the
same - The standard output of the spawned process is available only
after the process has finished execution.

Since the called batch file is run in a different process, i guess we
need some kind of Interprocess communication (IPC) to send the output
of the spawned process to the calling process (my C# windows app).

Something like this -
----------------------

My App Spawned Process (batch file)
------- ----------------------------
Create Process ----------------------> Process Created
.. some processing...
.. some processing...
.. some output...
Receive Notification <------------------Send output text to 'My App'
Display in window ..some processing..
.. some processing...
.. some output...
Receive Notification <------------------Send output text to 'My App'
Display in window ..some processing..
.. some processing...
.. some output...
Receive Notification <------------------Send output text to 'My App'
Display in window ..some processing..
..Process Exit
Display Completed

But right now its happenning like this -
----------------------------------------
My App Spawned Process (batch file)
------- ----------------------------
Create Process ----------------------> Process Created
.. some processing...
.. some processing...
.. some output...(buffered ??)
..some processing..
.. some processing...
.. some output...(buffered ??)
.. some processing...
.. some output...(buffered ??)
..some processing..
..Process Exit
Read the output<--------------------- Send output text to 'My App'
Display the output
Display Completed

It would be great if yuu could throw some light on the internal working
of Process.start and how the output is made available to the calling
process and in what sequence.

Thanks

Vijay



Ignacio Machin ( .NET/ C# MVP ) wrote:
hi,

I would do several changes:

First of all I would run this in a worker thread ( I will assume this)



p.StartInfo.RedirectStandardOutput = true;

while((output = myStreamReader.ReadLine())!=null)
{
string[] args = new string[1];
string[0] = output;
this.txtOutput.Invoke( UpdateOutput, args );
}

void UpdateTXTBOX( string line)
{
this.txtbox.Text+=line;
}

these are the declarations

public delegate void EventString( string line);

public EventString UpdateOutput = new EventString ( UpdateTXTBOX);



With that it should work.
Also consider change from a Textbox to something else, the strings
operations may have a performance impact.


cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation


Hi

I created a windows app to run a dos batch file (which takes around
5mins to complete and generates lots of output messages on the
console
in the meantime)and i used RedirectStandardOuput to display the
output
text in a textbox.

The problem is that till the batch file has not finished running i
don't get to see the output in the text box!!

How do we trap the output and display as and when its generated by
the
called app? can we get a LIVE UPDATE of the output?

Attached is part of the code for completeness :-

Your help will be greatly appreciated.

Thanks

Vijay

--------- CODE FOLLOWS -------------

// Create Process and Execute
p = new Process();

// Set Start Info
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow=false;
p.StartInfo.RedirectStandardOutput = false;
p.StartInfo.FileName = cmd;
p.StartInfo.WorkingDirectory="C:\\xyz\\";
p.Start();

StreamReader myStreamReader = p.StandardOutput;
// Read the standard output of the spawned process.
while((output = myStreamReader.ReadLine())!=null)
{
this.txtOutput.Text += output + "\r\n";
}
p.Close();
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top