代码之家  ›  专栏  ›  技术社区  ›  Lonnie Best

system.diagnostics.process(当一个进程内部使用另一个进程时)

  •  2
  • Lonnie Best  · 技术社区  · 15 年前

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

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

    令人沮丧的是,如果您使用cmd.exe(手动)执行非常相同的命令(我用system.diagnostics.process对象启动的命令),控制台将输出我在C应用程序中需要看到的每一行!

    但是,如果我(出于测试目的)使用system.diagnostics.process对象启动cmd.exe,并运行该命令,它仍然停止在与以前相同的点上输出(直接启动process1.exe);此时使用第二个.exe。我原以为这个测试会整合所有相关进程的所有输出,但事实并非如此。我如何才能将所有这些输出输入到我的C应用程序中?

    2 回复  |  直到 8 年前
        1
  •  5
  •   Nathan Wheeler    15 年前

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

        2
  •  1
  •   Community George Stocker    7 年前

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