473,326 Members | 1,972 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

redicting standard output

I have an application where I create a Plink process to communicate
with an HP Unix box. The problem I am having is that while reading the
redirected output, it seems to try to continue past the end and gets
caught in an endless loop. I am checking for the end of the output
like this:

while ((hj = puttyProcess.StandardOutput.ReadLine())!=null)

What am I doing wrong?

thanks,

Zenon

Apr 18 '06 #1
16 9274
Zenon wrote:
I have an application where I create a Plink process to communicate
with an HP Unix box. The problem I am having is that while reading the
redirected output, it seems to try to continue past the end and gets
caught in an endless loop. I am checking for the end of the output
like this:

while ((hj = puttyProcess.StandardOutput.ReadLine())!=null)

What am I doing wrong?


What do you mean by "continue past the end"?

Note that you should also be reading StandardError in another thread,
otherwise you could end up with plink blocking when it tries to write
to stderr.

Jon

Apr 18 '06 #2
I guess that I was assuming the thread was reading past the null which
signifies the end of the output and getting caught there. How do I
read StandardError into another thread?

thanks for your help

Z

Jon Skeet [C# MVP] wrote:
Zenon wrote:
I have an application where I create a Plink process to communicate
with an HP Unix box. The problem I am having is that while reading the
redirected output, it seems to try to continue past the end and gets
caught in an endless loop. I am checking for the end of the output
like this:

while ((hj = puttyProcess.StandardOutput.ReadLine())!=null)

What am I doing wrong?


What do you mean by "continue past the end"?

Note that you should also be reading StandardError in another thread,
otherwise you could end up with plink blocking when it tries to write
to stderr.

Jon


Apr 18 '06 #3
Zenon <ze****@comcast.net> wrote:
I guess that I was assuming the thread was reading past the null which
signifies the end of the output and getting caught there.
What evidence did you have for that? Are you sure it isn't just
blocking because plink hasn't finished?
How do I
read StandardError into another thread?


Create a new thread which has access to the Process reference, and do
exactly the same as you're doing for StandardOutput, but for
StandardError.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Apr 18 '06 #4
Sorry to keep re-posting, but I just can't get it to work. Here is my
code

//////////////////////////////////////////
// Start Plink process
puttyInfo.RedirectStandardInput = true;
puttyInfo.RedirectStandardOutput = true;
puttyInfo.UseShellExecute = false;
puttyInfo.RedirectStandardError = true;
puttyInfo.CreateNoWindow = true;
puttyInfo.Arguments = userName;
puttyInfo.FileName = "Plink.exe";
puttyProcess = Process.Start(puttyInfo);
puttyProcess.StandardInput.WriteLine(password);
StreamReader myStreamReader = puttyProcess.StandardError;

string hj = "";
string err = "";
while ((hj =puttyProcess.StandardOutput.ReadLine())!= null)
{
while((err = myStreamReader.ReadLine()) != null)
{
setTextBoxStatus(err);
}

setTextBoxStatus(hj);
}

It is hanging on
while((err = myStreamReader.ReadLine()) != null)

Apr 18 '06 #5
Zenon <ze****@comcast.net> wrote:
Sorry to keep re-posting, but I just can't get it to work. Here is my
code

//////////////////////////////////////////
// Start Plink process
puttyInfo.RedirectStandardInput = true;
puttyInfo.RedirectStandardOutput = true;
puttyInfo.UseShellExecute = false;
puttyInfo.RedirectStandardError = true;
puttyInfo.CreateNoWindow = true;
puttyInfo.Arguments = userName;
puttyInfo.FileName = "Plink.exe";
puttyProcess = Process.Start(puttyInfo);
puttyProcess.StandardInput.WriteLine(password);
StreamReader myStreamReader = puttyProcess.StandardError;

string hj = "";
string err = "";
while ((hj =puttyProcess.StandardOutput.ReadLine())!= null)
{
while((err = myStreamReader.ReadLine()) != null)
{
setTextBoxStatus(err);
}

setTextBoxStatus(hj);
}

It is hanging on
while((err = myStreamReader.ReadLine()) != null)


That's doing it in the same thread though - so it will block until
there's a line from standard output, then it'll block until the error
stream has finished (completely - i.e. until the process has
terminated).

As I said before, you need to start a new thread to read in.
If you're unfamiliar with threading, see
http://www.pobox.com/~skeet/csharp/threads

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Apr 18 '06 #6
"Zenon" <ze****@comcast.net> wrote:
I have an application where I create a Plink process to communicate
with an HP Unix box.


I did some work with plink and redirecting its input/output. (in
particular, I intercepted its "please enter your password" prompt).
The code's in C++, but maybe it'd still be helpful:

http://www.wischik.com/lu/programmer/unison-ssh.html

--
Lucian
Apr 19 '06 #7
I have read the c++ code as well as Johns and came up with this code.
I thought I had started a second thread for the error but it still
doesn't work.

//////////////////////////////////////////
// Start Plink process

ThreadStart errProc = new ThreadStart(readError);
Thread errThread = new Thread(errProc);
errThread.Start();

puttyInfo.RedirectStandardInput = true;
puttyInfo.RedirectStandardOutput = true;
puttyInfo.UseShellExecute = false;
puttyInfo.RedirectStandardError = true;
puttyInfo.CreateNoWindow = true;
puttyInfo.Arguments = userName;
puttyInfo.FileName = "Plink.exe";
puttyProcess = Process.Start(puttyInfo);
puttyProcess.StandardInput.WriteLine(password);

string hj = "";
while ((hj =puttyProcess.StandardOutput.ReadLine())!= null)
{
hj = puttyProcess.StandardOutput.ReadLine();
setTextBoxStatus(hj);
textBoxStatus.Select(textBoxStatus.MaxLength, 0);
textBoxStatus.ScrollToCaret();
}

public void readError()
{

string yy = "";
while((yy = puttyProcess.StandardError.ReadLine()) != null)
{
setTextBoxStatus(yy);
MessageBox.Show(yy);
textBoxStatus.Select(textBoxStatus.MaxLength, 0);
textBoxStatus.ScrollToCaret();

}
}

Thanks for your help, and patience.

Apr 19 '06 #8
I've checked out bot your example and John's article and came up with
this. I start a second thread to handle the redirected error but keep
the main plink process the same. Unfortunately, I still can't get this
to work. I do know that blocking is a problem because if I kill a
plink process in task manager, the code continues to execute. Thanks
for your help and patience.

//////////////////////////////////////////
// Start Plink process

ThreadStart errProc = new ThreadStart(readError);
Thread errThread = new Thread(errProc);
errThread.Start();

puttyInfo.RedirectStandardInput = true;
puttyInfo.RedirectStandardOutput = true;
puttyInfo.UseShellExecute = false;
puttyInfo.RedirectStandardError = true;
puttyInfo.CreateNoWindow = true;
puttyInfo.Arguments = userName;
puttyInfo.FileName = "Plink.exe";
puttyProcess = Process.Start(puttyInfo);
puttyProcess.StandardInput.WriteLine(password);

string hj = "";
while ((hj =puttyProcess.StandardOutput.ReadLine())!= null)
{
hj = puttyProcess.StandardOutput.ReadLine();
setTextBoxStatus(hj);
textBoxStatus.Select(textBoxStatus.MaxLength, 0);
textBoxStatus.ScrollToCaret();
}

public void readError()
{

string yy = "";
while((yy = puttyProcess.StandardError.ReadLine()) != null)
{
setTextBoxStatus(yy);
MessageBox.Show(yy);
textBoxStatus.Select(textBoxStatus.MaxLength, 0);
textBoxStatus.ScrollToCaret();
Thread.Sleep(1000);
Thread.CurrentThread.Abort();
}
}

Apr 19 '06 #9
Zenon <ze****@comcast.net> wrote:
I've checked out bot your example and John's article and came up with
this. I start a second thread to handle the redirected error but keep
the main plink process the same. Unfortunately, I still can't get this
to work. I do know that blocking is a problem because if I kill a
plink process in task manager, the code continues to execute.


So, it sounds like plink isn't exiting when you expect it to. What are
you doing which should make it exit?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Apr 19 '06 #10
Actually, I am not expecting it to exit, I just forced it to do so to
determine whether it was the cause of the "hang-up". At this point, I
have just started a plink process and logged in. I want to now begin
sending it commands (run executables resident on the UNIX machine).
Did I set up my second thread correctly? Is there anything I am
missing?

Apr 19 '06 #11
Zenon <ze****@comcast.net> wrote:
Actually, I am not expecting it to exit, I just forced it to do so to
determine whether it was the cause of the "hang-up". At this point, I
have just started a plink process and logged in. I want to now begin
sending it commands (run executables resident on the UNIX machine).
Did I set up my second thread correctly? Is there anything I am
missing?


If you're not expecting it to exit, then the two threads reading the
standard output and standard error will certainly block - they're meant
to. They will block until the program has finished, as otherwise they
won't know whether there's more data to come.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Apr 19 '06 #12
Jon Skeet [C# MVP] <sk***@pobox.com> wrote:
So, it sounds like plink isn't exiting when you expect it to. What are
you doing which should make it exit?


As far as I remember, PLINK has two modes of execution:

(1) interactive shell. You start it, and it launches a remote shell
with redirected input/output. Once that remote shell has terminated,
then PLINK will also close its input+output handles. (How to close the
remote shell? -- normally by sending it CTRL-D, or typing "exit" or
"logout", but it depends on which remote shell is being used.)

(2) single-command. You pass a single command-string as an argument to
plink. It will open the connection and execute the command remotely,
redirecting input+output. If ever that command terminates, then the
PLINK's input+output handles will also close. (When will that remote
command terminate? -- it depeds entirely on the command.)

--
Lucian
Apr 19 '06 #13
This article may or may not help:

http://www.geocities.com/Jeff_Louie/multi-threaded.htm

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***
Apr 20 '06 #14
It looks to me that the problem is not with StandardError blocking
StandardOutput, but instead, StandardOutput's charBuffer is
overflowing. As I read the redirected output, everything works well
until the buffer gets to about 980 bytes. On the next pass it crashes.
Is there a way to clear the buffer? I tried DiscardBufferedData, but
that didn't seem to work.

thanks again

Jeff Louie wrote:
This article may or may not help:

http://www.geocities.com/Jeff_Louie/multi-threaded.htm

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***


Apr 20 '06 #15
No, you just need to read it. I looked at your code from the 19th and
you're still not launching a thread to read from the outputstream.

You need something like this:

Process p = new Process();
p.StartInfo.FileName = "MyProg.exe";
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute=false;

if(p.Start())
{
ManualResetEvent readerEvent = new ManualResetEvent(false);
StreamPoller errorPoller = new
StreamPoller(readerEvent,p.StandardOutput);
Thread outputThread = new Thread(new ThreadStart(outputPoller.Poll));
outputThread.Start();
p.WaitForExit();
readerEvent.Set();
...
}

public class StreamPoller
{

ManualResetEvent _readEvent;
StreamReader _reader;

public StreamPoller(ManualResetEvent readEvent,StreamReader reader)
{
_readEvent = readEvent;
_reader = reader;

}

public void Poll()
{

while(true)
{
if(_readEvent.WaitOne(1,true))
{
break;
}
//do whatever you want here with the redirected stdout
Console.Writeline(_reader.ReadLine());
}
}
}

Apr 20 '06 #16
Thanks very much for your help and code sample. I'm still working
through it and trying to completely understand it instead of pasting it
into my app without understanding it.

I learned an interesting thing with my code. If I add a line like
puttyProcess.StandardInput.WriteLine(something) in the read loop, the
code does not lock up. Does this WriteLine function empty some shared
read/write buffer? I realize that this doesn't make sense but....
Why would this writing affect the reading?

Apr 24 '06 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Brian | last post by:
I'm running a dos program via System.Diagnostics.Process. The dos program is very picky about filenames and such, and so I want to show the output to the user so they can verify it did what it...
3
by: beliavsky | last post by:
I want to write a function that writes to an output file if specified and otherwise to standard output. How can I connect a file object to standard output in the code below? I could use an if...
4
by: Barry | last post by:
Hi, guys Basiclly, it is automated testing system. There is a main python script that handles the testing campagin. This main script will call another script that will in turn runs a few...
14
by: fdu.xiaojf | last post by:
Hi, I'm writing a program which imports an external module writing in C and calls a function provided by the module to do my job. But the method produces a lot of output to the stdout, and this...
18
by: rajpal_jatin | last post by:
int main() { int k; union jatin{ int i :5; char j :2; }; union jatin rajpal; k= sizeof(rajpal);
2
by: Devine123 | last post by:
Hi, I’m creating a perl script that takes incoming http/s requests, logs the standard input, output and error, before returning the output to the client. The input, output and error log is appended...
14
by: =?Utf-8?B?R2lkaQ==?= | last post by:
Hi, In my windows applicationm, i need to excute a batch file. this batch file throws some text and questions to the screen, i need to catch the standard Output, check if it's a question, in...
1
by: TP | last post by:
Hi everybody, I try to find a quick way to redirect the standard output of a Python command (for example: print "message") to a python variable "foobar". Ok, in this simple example, I could do...
27
by: CarlosMB | last post by:
Hello, I am writing code that uses a DLL which is supposed to print to console some useful information but for some reason it is not doing so. The environment is a bit complex to explain but...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.