【问题标题】:System.Diaganostics.Process (when one process internally uses another)System.Diagnostics.Process(当一个进程在内部使用另一个时)
【发布时间】:2011-01-06 13:44:15
【问题描述】:

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

我正在“内部”监控的进程会启动第二个进程,一旦启动,我就不会从进程对象收到更多输出。

令人沮丧的是,如果您使用 cmd.exe(手动)执行相同的命令(我使用 System.Diagnostics.Process 对象启动),控制台会输出我需要在我的C# 应用程序!

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

【问题讨论】:

    标签: c# ssh cmd system.diagnostics openssh


    【解决方案1】:

    原因是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 循环)持续监控的新线程,并在单独的类,或者只是将第三个进程的输出重新路由到第二个进程的输出的处理程序中,这样您就可以使用一个方法来处理两个进程的所有输出。

    【讨论】:

    • 首先,我很惊讶您如此迅速地回复了如此详细的信息,非常感谢您的帮助。从第一个进程的输出中,我可以确定第二个进程“启动”的时间点。
    • 糟糕的是,.Net 框架中没有一个对象可以像 cmd.exe 一样出色的“进程输出合并器”(手动运行时)。
    • 感谢您的努力,但我还是遇到了这个问题:stackoverflow.com/questions/2095826/…
    【解决方案2】:

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

    【讨论】:

    • 不,我只尝试启动 cmd.exe,因为我希望它会显示所有进程的所有输出。我最初按照您提到的方式尝试了它,并且在第一个进程开始使用第一个进程在内部调用的第二个进程后,输出(使用您引用的问题中的技术)停止了。
    猜你喜欢
    • 2016-03-03
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 2013-01-16
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多