System.Diagnostics.Process(当一个进程在内部使用另一个进程时)

时间:2010-01-18 22:13:09

标签: c# ssh cmd system.diagnostics openssh

我一直在使用C#System.Diagnostics.Process来监视命令行实用程序的输出。

我正在“内部”监视的进程启动第二个进程,一旦进行,我就不再收到进程对象的进一步输出。

令人沮丧的是,如果你使用cmd.exe(手动)执行相同的命令(我正在使用System.Diagnostics.Process对象启动),控制台会输出我需要在我看到的每一行C#app!

但是,如果我(出于测试目的)使用System.Diagnostics.Process对象启动cmd.exe并运行该命令,它仍然会停止输出与之前相同的点(直接启动process1.exe);在使用second.exe时。我认为这个测试会整合所有相关过程的输出,但事实并非如此。如何将所有这些输出都输入到我的C#应用​​程序中?

2 个答案:

答案 0 :(得分:5)

原因是System.Diagnostics.Process实际上只是监视它所连接的进程。

解决此问题的一种方法是第一个应用程序在启动第二个应用程序时输出,当收到该输出时,从主应用程序监视从(现在是第三个)应用程序创建进程。第三个应用程序启动后,它应该出现在System.Diagnostics.Process.GetProcesses()数组中,然后您可以附加到它的OutputDataReceived事件。

您的代码看起来像这样(未经测试):

private void firstProcess_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    if (e.Data == "Starting next process")
    {
        System.Diagnostics.Process newProcess = null;

        while (newProcess == null)
        {
            System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcesses();

            foreach (System.Diagnostics.Process proc in procs)
            {
                if (proc.ProcessName == "newProcess")
                {
                    newProcess = proc;
                    break;
                }
            }

            System.Threading.Thread.Sleep(100);
        }

        newProcess.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(newProcess_OutputDataReceived);
    }
}

void newProcess_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    // Do something with your data received here.
}

请注意,这只是一个示例,如果您的第三个进程无法启动或结束太快,则此方法将挂起无限循环。此示例仅用于为您提供构建适合您特定情况的内容的知识,我并不完全熟悉。您应该至少确保while循环不会永远持续,并且您可能还想进行一些其他调整。

编辑:或者,如果您无法将源修改为第一个应用程序,您可以简单地创建一个以这种方式监视的新线程(使用while循环)并在单独的第三个进程中处理输出class,或者简单地将第三个进程的输出重新路由到第二个进程输出的处理程序中,这样你就可以有一个方法来处理这两个进程的所有输出。

答案 1 :(得分:1)

您是否需要启动cmd.exe?你不能直接在你的进程中启动rsync进程,然后使用this question中描述的技术来捕获命令执行的输出,以便你可以在代码中使用它们吗?