Reputation: 607
is there a way to indicate if a process like standard calculator got an output or not,
i need it because i have this line :
sr = p1.StandardOutput;
and i need to do this :
s = sr.ReadLine();
only if there's an output from p1
in calculator for example there's no output so the program stuck after the ReadLine
.
thanks all.
the code :
while (i < asProcesses.Length - 1)
{
if ((i + 1) == asProcesses.Length - 1 && sOutRedirect != "")
break;
p1.StartInfo.RedirectStandardOutput = true;
p1.StartInfo.FileName = asProcesses[i];
p1.StartInfo.UseShellExecute = false;
if(i==0)
p1.Start();
sr = p1.StandardOutput;
Process p2 = new Process();
p2.StartInfo.RedirectStandardInput = true;
p2.StartInfo.FileName = asProcesses[i + 1];
p2.StartInfo.UseShellExecute = false;
p2.Start();
sw = p2.StandardInput;
while (!sr.EndOfStream && s != null)
{
s = sr.ReadLine();
if (s != null)
{
sw.WriteLine(s);
}
}
if (sw != null)
sw.Close();
if (sr != null)
sr.Close();
i++;
}
Upvotes: 1
Views: 1101
Reputation: 1140
If all processes exit after executing, use this instead of the inner while:
p1.WaitForExit();
sw.Write(sr.ReadToEnd());
If you want the processes to time out:
int i = 0;
while (!p1.HasExited && i < maxWaits)
{
Thread.Sleep(delay);
i++;
}
sw.Write(sr.ReadToEnd());
//Kill process if running:
if (!p1.HasExited)
{
try { p1.Kill(); }
catch { }
}
It seems you're trying to chain the output from each process to the next one. If that's the case, you're missing a p1 = p2
at the end of the loop.
Also, consider to move the first starting process out of the loop: It will make your code much more readable. Setting p1
's StartInfo should be moved into the if (i == 0)
block if you leave it this way. Moving the output read last process out wouldn't be a bad idea either, in my opinion...
This is my solution (with timing out):
int maxWaits = 10; // Wait 1 second at most.
int delay = 100;
var p = new Process();
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = asProcesses[0];
p.StartInfo.UseShellExecute = false;
p.Start();
foreach (var path in asProcesses.Skip(1))
{
var p2 = new Process();
p2.StartInfo.FileName = path;
p2.StartInfo.RedirectStandardInput = true;
p2.StartInfo.RedirectStandardOutput = true;
p2.StartInfo.UseShellExecute = false;
{
int i = 0;
while (!p.HasExited && i < maxWaits)
{
p2.StandardInput.Write(p.StandardOutput.ReadToEnd()); //Redirect IO. This line means that the second process can start calculations if the first is long-running and writes its output progressively.
Thread.Sleep(delay);
i++;
}
}
p2.StandardInput.Write(p.StandardOutput.ReadToEnd()); //Redirect last output from p.
{
//Kill process if still running:
if (!p.HasExited)
{
try { p.Kill(); }
catch { }
}
}
}
{
int i = 0;
while (!p.HasExited && i < maxWaits)
{
Thread.Sleep(delay);
i++;
}
}
string result = p.StandardOutput.ReadToEnd();
{
if (!p.HasExited)
{
try { p.Kill(); }
catch { }
}
}
Algorithm that waits for each process to exit:
var p = new Process();
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = asProcesses[0];
p.StartInfo.UseShellExecute = false;
p.Start();
foreach (var path in asProcesses.Skip(1))
{
var p2 = new Process();
p2.StartInfo.FileName = path;
p2.StartInfo.RedirectStandardInput = true;
p2.StartInfo.RedirectStandardOutput = true;
p2.StartInfo.UseShellExecute = false;
p.WaitForExit();
p2.StandardInput.Write(p.StandardOutput.ReadToEnd());
}
p.WaitForExit();
string result = p.StandardOutput.ReadToEnd();
I moved the first process out of the loop to get rid of the conditional. The control flow is simpler this way and it's easier to add code affection the first process specifically.
Upvotes: 0
Reputation: 5087
void foo()
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "c:\\windows\\system32\\ping.exe";
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.EnableRaisingEvents = true;
p.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(p_OutputDataReceived);
p.Start();
p.BeginOutputReadLine();
}
void p_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
string s = e.Data;
// process s
}
Upvotes: 1