了解如何使用System.Diagnostics.Process控制stdout

时间:2013-01-10 18:47:37

标签: c# .net doxygen

我看到几个关于如何启动进程并将数据推送到stdin的问题,但不知道如何控制输出的位置。

首先是我当前的代码,从控制台模式C#应用程序运行:

    // Prepare the process to run
    ProcessStartInfo start = new ProcessStartInfo();
    // Enter in the command line arguments, everything you would enter after the executable name itself
    start.Arguments = " -";
    // Enter the executable to run, including the complete path
    start.FileName = "doxygen.exe";
    // Do you want to show a console window?
    start.WindowStyle = ProcessWindowStyle.Normal;
    start.CreateNoWindow = false;
    start.RedirectStandardInput = true;
    start.UseShellExecute = false;

    // Run the external process & wait for it to finish
    using (Process proc = Process.Start(start))
    {
        //doxygenProperties is just a dictionary
        foreach (string key in doxygenProperties.Keys)
            proc.StandardInput.WriteLine(key+" = "+doxygenProperties[key]);
        proc.StandardInput.Close();
        proc.WaitForExit();

        // Retrieve the app's exit code
        int exitCode = proc.ExitCode;
    }

当我运行它时会发生什么?我看到任何新窗口(虽然我认为我应该)并且所有doxygen.exe的stdout都会打印到我应用程序的控制台窗口。

我想要发生的是两件事之一:

  1. Doxygen在可见窗口中启动,我可以在该窗口中看到它的stdout,而不是在我的应用程序窗口中。
  2. Doxygen在隐藏窗口中启动,它的stdout被写入日志文件。
  3. 我如何实现这些目标?

    另外,为什么我没有为衍生进程创建一个单独的窗口,为什么生成的进程将输出写入我的窗口而不是它自己的?

2 个答案:

答案 0 :(得分:2)

您可以做的一件事是使用RedirectStandardOutput,而不是使用WaitForExit,您可以使用ReadToEnd

ProcessStartInfo start = new ProcessStartInfo();
start.RedirectStandardOutput = true;

//make other adjustments to start

Process p = new Process();
p.StartInfo = start;
p.Start();
string output = p.StandardOutput.ReadToEnd();

然后您可以在闲暇时使用string output


如果要实时获取输出,p.StandardOutput属性具有允许您异步获取输出的方法。我不知道它的所有细节,我之前只使用过一次,但如果你搜索它,那里有很多文献。


同时重定向StandardOutputStandardError时也要小心,如果它们足够长,则可能导致死锁。

答案 1 :(得分:0)

你需要做两件事:

1)通过在此过程中将RedirectStandardOuput属性设置为true,表明您希望将流程的标准输出定向到您的应用。

2)在调用WaitForExit之前,开始捕获输出:

string sOutput = p.StandardOutput.ReadToEnd();

如果在调用wait for exit之前没有开始读取输出,则可能会遇到死锁。

但是,重要的是要知道标准输出只会捕获输出信息,而不是写入应用程序标准错误流的任何信息。

为了捕获两个信息流,您可以挂钩进程的OutputDataReceivedErrorDataReceived事件,并将事件数据直接写入日志文件或将其存储在类属性中以供在过程已经完成。