【问题标题】:Understanding how to control stdout using System.Diagnostics.Process了解如何使用 System.Diagnostics.Process 控制标准输出
【发布时间】:2013-01-10 18:47:37
【问题描述】:

我看到了几个关于如何启动进程并将数据推送到标准输入的问题,但没有看到如何控制它们的输出去向。

首先是我当前的代码,从控制台模式 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 的标准输出都打印到我的应用程序的控制台窗口。

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

  1. Doxygen 在可见窗口中启动,我可以在该窗口中看到它的标准输出,而不是在我的应用程序窗口中。
  2. Doxygen 在隐藏窗口中启动,并将其标准输出写入日志文件。

我怎样才能实现这些?

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

【问题讨论】:

  • 所以您没有注意到RedirectStandardOutput 属性或StandardOutput 属性,并且您没有检查您正在设置的属性的文档,例如CreateNoWindow 其中明确指出是否显示窗口?该文档的存在是有原因的。此外,还讨论了很多重定向输出。我很难相信您很难找到有关该主题的讨论。
  • 文档 (msdn.microsoft.com/en-us/library/…) 很糟糕。它对这些事情中的每一个进行了单行解释,而没有解释它们的实际含义。例如,为什么根据我的设置没有出现新窗口,为什么生成的进程的标准输出出现在我的应用程序的窗口中,而不是它自己的?
  • 至少并不可怕。 StandardOutput 的文档包含几段文本和多个代码示例。看来您只是认为文档很烂,甚至没有看它。
  • @Servy 文档解释了我如何捕获标准输出,这恰好回答了我的问题的一部分:第 2 点。我没有看到任何解释为什么生成的进程将标准输出写入我的应用程序的标准输出没有任何重定向,或者为什么即使我设置了start.WindowStyle = ProcessWindowStyle.Normal; start.CreateNoWindow = false;,生成的应用程序也没有显示新窗口

标签: c# .net doxygen


【解决方案1】:

您可以做的一件事是使用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 时也要小心,如果它们足够长,可能会导致死锁。

【讨论】:

    【解决方案2】:

    你需要做两件事:

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

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

    string sOutput = p.StandardOutput.ReadToEnd();
    

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-22
      • 2013-01-11
      • 1970-01-01
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多