如何检查进程是否获得输出?

时间:2011-03-02 18:49:15

标签: c# input stream

有没有办法表明像标准计算器这样的过程是否得到了输出,
我需要它,因为我有这条线:

sr = p1.StandardOutput;  

我需要这样做:

s = sr.ReadLine();  

只有来自p1的输出 例如,在计算器中没有输出,因此程序在ReadLine之后停留 谢谢大家。

代码:

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++;
            }

2 个答案:

答案 0 :(得分:0)

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
}

答案 1 :(得分:0)

如果所有进程在执行后退出,请使用此而不是内部while:

p1.WaitForExit();
sw.Write(sr.ReadToEnd());

如果您希望进程超时:

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 { }
}

编辑:

您似乎正在尝试将每个流程的输出链接到下一个流程。如果是这种情况,那么在循环结束时你会错过p1 = p2 另外,考虑将第一个启动过程移出循环:它将使您的代码更具可读性。设置p1的StartInfo应该移到if (i == 0)块中,如果你这样做的话。在我看来,移动输出读取最后一个过程也不是一个坏主意......

编辑:

这是我的解决方案(超时):

        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 { }
            }
        }

编辑:

等待每个进程退出的算法:

        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();

我将第一个进程移出循环以摆脱条件。控制流程更简单,特别是第一个过程更容易添加代码。