了解如何使用System.Diagnostics.Process控制标准输出

本文关键字:Process 控制 标准输出 Diagnostics System 何使用 了解 | 更新日期: 2023-09-27 17:51:12

我看到了几个关于如何启动进程和将数据推入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;
    }

当我运行这是我做看到任何新的窗口(虽然我认为我应该)和所有的氧。exe的stdout打印到我的应用程序的控制台窗口。

我希望发生的是两件事之一:

    氧是在一个可见的窗口中启动的,我可以在那个窗口中看到它的stdout,而不是在我的应用程序的窗口中。氧在一个隐藏的窗口中启动,它的标准输出被写入日志文件。

我如何才能实现这些?

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

了解如何使用System.Diagnostics.Process控制标准输出

你可以用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)通过在进程中设置RedirectStandardOuput属性为true,表明你希望将进程的标准输出定向到你的应用程序。

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

string sOutput = p.StandardOutput.ReadToEnd();

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

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

为了捕获这两个信息流,您可以钩住流程的OutputDataReceived和ErrorDataReceived事件,并将事件数据直接写入日志文件或将其存储在类属性中,以便在流程完成后使用。