Continuously redirecting shell output

D

David Meier

Hi list,

I wonder if there is a way in C# to continuously redirect shell output
to a text box.

That's what I am doing: I call rsync.exe which runs within a cygwin
shell. Now, I want to display the stdout as soon as it gets written. I
use System.Diagnostics and it works fine but it waits for the rsync
process to terminate before writing stdout to the text box.

Process rsync = new Process();
ProcessStartInfo rsync_info = new
ProcessStartInfo(@"/path/to/rsync.exe");

rsync_info.CreateNoWindow = true;
rsync_info.UseShellExecute = false;
rsync_info.RedirectStandardOutput = true;

rsync.StartInfo = rsync_info;
rsync.Start();
string output = rsync.StandardOutput.ReadToEnd();
rsync.WaitForExit();

this.myTextBox.AppendText(output);

Any ideas, hints and comments on this are highly welcome! Thanks.

Dave
 
S

Scott Allen

You could use StandardOutput.Base.BeginRead to read asynchronously.

When you invoke BeginRead, you specify a method for the runtime to
invoke when there is data available (a callback).

Inside of the callback, you can read the data that is available, and
then move the text into the TextBox. Be sure to use Control.Invoke, as
the Callback happens on a non-UI thread. See Jon's information here:
http://www.yoda.arachsys.com/csharp/multithreading.html#windows.forms

Inside the callback then, you'll want to start another BeginRead
operation to fetch more data as it arrives.
 
S

Scott Allen

Excellent! This adds a nice touch.

--s

Never mind. Figured this one out myself:

:
txtOutput.Text += e.Output;
txtOutput.SelectionStart = this.txtOutput.Text.Length;
txtOutput.ScrollToCaret();
:

Cheers!
 
S

Sam Jost

David,

have you tried to use

txtOutput.AppendText( e.Output);

instead? It should look 'smoother' (no flickering like +=) and in case
of the Textbox scroll to the end without need for interaction.

Sam
--
now if only RichTextBox would scroll to the end with this, too...


David Meier said:
Never mind. Figured this one out myself:

:
txtOutput.Text += e.Output;
txtOutput.SelectionStart = this.txtOutput.Text.Length;
txtOutput.ScrollToCaret();
:

Cheers!

[...lots o stuff..]
 
G

Guest

Hello Scott,

I wonder if a pop-up window with a text box could be created when standard input is needed while using your code?

Should the StreamWriter be created similar to the StreamReaders? How about the callback function?

Thanks, Dave.
 
S

Scott Allen

Hi David:

I'm sure you could take input from a user and pump it into standard
input. As I'm thinking of it though - the trick would be how to know
*when* to prompt for the input. If you look for a certain string in
the output stream and know that it prompts the user it would help, but
I don't know of a way to do it generically.

You could create the StreamWriter in a similar fashion along with the
callback to call EndInvoke.
 

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