我如何检查进程是否有输出?

发布于 2024-10-20 00:11:42 字数 1426 浏览 1 评论 0原文

有没有办法指示标准计算器等进程是否有输出,
我需要它,因为我有这一行:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

£冰雨忧蓝° 2024-10-27 00:11:42
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
}
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
}
七分※倦醒 2024-10-27 00:11:42

如果所有进程在执行后退出,请使用它而不是内部 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();

我移动了第一个进程跳出循环以摆脱条件。这种方式控制流程更简单,并且更容易专门向第一个进程添加代码影响。

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

Edit:

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...

Edit:

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

Edit:

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文