Problem while communicating with external application via redirected stdin-stdout

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
Hello, everybody.<br/> <br/> I am writing C# application which have to communicate with external console interactive application (written using C++).<br/> Protocol of communication is very simple: reading couple of lines from stdout - analyze output - writing couple of lines to stdin.<br/> <br/> I faced with problem: reading stdout and stderr hangs (does not occures) when external application waits for input (from stdin).<br/> <br/> What I tried to do:<br/> 1. Asynchronous read stderr/strdout - ErrorDataReceived and OutputDataReceived handlers never called<br/> 2. Read stdout/stderr in separate threads to avoid buffer lock problem. Execution stops in Read, ReadLine, ReadToEnd, Peek and never return, until called process is alive.<br/> <br/> If process terminated manually - all output becomes available via read functions.<br/> <br/> Sample code (with asynchronous read):<br/> <br/>    
<div style="color:Black;background-color:White
<pre> <span style="color:Blue void
RunApp(<span style="color:Blue string
exec, <span style="color:Blue string
args, <span style="color:Blue string
workdir)
{
process = <span style="color:Blue new
Process();
process.StartInfo.RedirectStandardOutput = <span style="color:Blue true
;
process.StartInfo.RedirectStandardError = <span style="color:Blue true
;
process.StartInfo.RedirectStandardInput = <span style="color:Blue true
;
process.StartInfo.CreateNoWindow = <span style="color:Blue false
;
process.StartInfo.UseShellExecute = <span style="color:Blue false
;
process.StartInfo.FileName = exec;
process.StartInfo.Arguments = args;
process.StartInfo.WorkingDirectory = workdir;

process.ErrorDataReceived += <span style="color:Blue new
DataReceivedEventHandler(process_ErrorDataReceived);
process.OutputDataReceived += <span style="color:Blue new
DataReceivedEventHandler(process_OutputDataReceived);

<span style="color:Blue if
(process.Start())
{
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.WaitForExit();
}
}

<span style="color:Blue void
process_ErrorDataReceived(<span style="color:Blue object
sender, DataReceivedEventArgs e)
{
Trace.WriteLine(<span style="color:#a31515 "STDERR:"
+ e.Data);
}<br/>
<span style="color:Blue void
process_OutputDataReceived(<span style="color:Blue object
sender, DataReceivedEventArgs e)
{
Trace.WriteLine(<span style="color:#a31515 "STDOUT:"
+ e.Data);
process.StarndardInput.WriteLine(<span style="color:#a31515 "stop"
);
}
[/code]

<br/> <br/> My assumption: processs output and error stream internal buffers never reach its limit and streams does not closes, so it leads to infinite waiting in stream read methods. But I am not sure<br/> <br/> What I do wrong?<br/> Is there any way to communicate with interactive console applications?<br/> <br/> Thank you for your comments and answers.<br/> <br/> Alexander.

View the full article
 
Back
Top