简体   繁体   English

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

[英]Understanding how to control stdout using System.Diagnostics.Process

I see several questions about how to launch processes and push data into stdin, but not how to control where their output goes. 我看到几个关于如何启动进程并将数据推送到stdin的问题,但不知道如何控制其输出的位置。

First here is my current code, run from a console mode C# application: 首先是我当前的代码,从控制台模式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;
    }

What happens when I run this is I do not see any new window (though I think I should) and all of doxygen.exe's stdout is printed to my app's console window. 当我运行它时会发生什么是我没有看到任何新窗口(虽然我认为我应该)并且所有doxygen.exe的标准输出都打印到我的应用程序的控制台窗口。

What I would like to happen is one of two things: 我想要发生的是两件事之一:

  1. Doxygen is launched in a visible window, and I can see its stdout in that window, not in my app's window. Doxygen在可见窗口中启动,我可以在该窗口中看到它的标准输出,而不是在我的应用程序窗口中。
  2. Doxygen is launched in a hidden window, and it's stdout is written to a log file. Doxygen在隐藏窗口中启动,它的stdout被写入日志文件。

How can I achieve these? 我怎样才能实现这些目标?

In addition, why am I not getting a separate window for the spawned process, and why is the spawned process writing output to my window not its own? 另外,为什么我没有为生成的进程获取单独的窗口,为什么生成的进程将输出写入我的窗口而不是它自己的?

One thing that you can do is use RedirectStandardOutput and instead of using WaitForExit you can use ReadToEnd 你可以做的一件事是使用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();

and then you can use string output at your leisure 然后你可以在闲暇时使用string output


If you want to get output in real-time the p.StandardOutput property has methods that allow you to get the output asynchronously. 如果要实时获得输出, p.StandardOutput属性具有允许您异步获取输出的方法。 I don't know all the details to it offhand, I've only used it once before, but there's plenty of literature out there if you search for it. 我不知道它的所有细节,我以前只使用过一次,但如果你搜索它,那里有很多文献。


Also be careful when redirecting both StandardOutput and StandardError at the same time, If they're long enough, it is possible for that to cause deadlocks. 在同时重定向StandardOutputStandardError时也要小心,如果它们足够长,则可能导致死锁。

You need to do two things: 你需要做两件事:

1) Indicate that you want the standard output of the process to be directed to your app by setting the RedirectStandardOuput property to true in the process. 1)通过在流程中将RedirectStandardOuput属性设置为true,表明您希望将流程的标准输出定向到您的应用程序。

2) BEFORE the call to WaitForExit , start capturing the output: 2)在调用WaitForExit之前,开始捕获输出:

string sOutput = p.StandardOutput.ReadToEnd();

If you do not start reading the output before calling wait for exit, you can encounter a deadlock. 如果在调用wait for exit之前没有开始读取输出,则可能会遇到死锁。

However, it is important to know that standard output will only capture output information, not anything written to the standard error stream of the app. 但是,重要的是要知道标准输出只捕获输出信息,而不是写入应用程序标准错误流的任何内容。

In order to capture both streams of information, you can hook the process's OutputDataReceived and ErrorDataReceived events and write the event data directly into a log file or store it in a class property for use after the process has completed. 为了捕获两个信息流,您可以挂钩进程的OutputDataReceivedErrorDataReceived事件,并将事件数据直接写入日志文件或将其存储在类属性中,以便在进程完成后使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM