【问题标题】:process.standardoutput.ReadToEnd() always empty?process.standardoutput.ReadToEnd() 总是空的?
【发布时间】:2018-03-21 03:34:26
【问题描述】:

我正在启动一个控制台应用程序,但是当我重定向标准输出时,我总是一无所获!

当我不重定向它并将CreateNoWindow 设置为false 时,我可以在控制台中正确看到所有内容,但是当我重定向它时,StandardOutput.ReadToEnd() 总是返回一个空字符串。

        Process cproc = new Process();
        cproc.StartInfo.CreateNoWindow = true;
        cproc.StartInfo.FileName = Dest;
        cproc.StartInfo.RedirectStandardOutput = true;
        cproc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        cproc.StartInfo.UseShellExecute = false;
        cproc.EnableRaisingEvents = true;
        cproc.Start();
        cproc.Exited += new EventHandler(cproc_Exited);
        while(!stop)
        {
           result += cproc.StandardOutput.ReadToEnd();
        }

EventHandler cproc_exited 只是将stop 设置为true。谁能解释为什么result 总是string.Empty

【问题讨论】:

    标签: c# process


    【解决方案1】:

    最好的方法是重定向输出并等待事件:

        // not sure if all this flags are needed
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.ErrorDialog = false;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.RedirectStandardInput = true;
        process.StartInfo.RedirectStandardOutput = true;
        process.EnableRaisingEvents = true;
        process.OutputDataReceived += process_OutputDataReceived;
        process.ErrorDataReceived += process_ErrorDataReceived;
        process.Exited += process_Exited;
        process.Start();
    
        void process_Exited(object sender, System.EventArgs e)
        {
            // do something when process terminates;
        }
    
        void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            // a line is writen to the out stream. you can use it like:
            string s = e.Data;
        }
    
        void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            // a line is writen to the out stream. you can use it like:
            string s = e.Data;
        }
    

    【讨论】:

      【解决方案2】:

      为什么要循环播放?一旦它读到最后,它就不能再读取任何数据了,是吗?

      您确定文本实际上是写入StandardOutput 而不是StandardError

      (是的,显然您希望将 RedirectStandardOutput 设置为 true 而不是 false。我认为这只是您复制了错误版本的代码的情况。)

      编辑:正如我在 cmets 中所建议的,您应该在单独的线程中读取标准输出和标准错误。 不要等到进程退出 - 这可能会导致死锁,您正在等待进程退出,但进程正在阻止尝试写入 stderr/stdout,因为您没有'不从缓冲区中读取。

      您也可以订阅 OutputDataReceived 和 ErrorDataReceived 事件,以避免使用额外的线程。

      【讨论】:

      • 如果我把它改成 while (!stop) { } s += convproc.StandardOutput.ReadToEnd();我遇到了僵局
      • 嘿,它有效!看起来我的朋友(他制作了控制台程序)搞砸了!它将所有内容写入错误流!我得和他谈谈,也许他能解决这个问题。感谢您的快速答复!你让我免于坐在我的电脑前几个小时并试图搜索一个愚蠢的错误:)
      • @alex:去掉那个while循环——它不应该在那里。理想情况下,使用单独的线程 - 一个从 StandardOutput 读取,一个从 StandardError 读取。
      • 好吧,我现在把它从ReadToEnd改成了ReadLine
      • @alex:在这种情况下,您需要一个循环(直到 ReadLine 返回 false) - 但除非您在流程完成之前确实需要数据,否则我强烈建议您从两个线程中使用 ReadToEnd(一个用于 stdout,一个用于 stderr)。
      【解决方案3】:

      您已禁用标准输出重定向。尝试改变

      cproc.StartInfo.RedirectStandardOutput = false;
      

      进入

      cproc.StartInfo.RedirectStandardOutput = true;
      

      MSDN 的以下示例对您有用吗?

      // Start the child process.
      Process p = new Process();
      // Redirect the output stream of the child process.
      p.StartInfo.UseShellExecute = false;
      p.StartInfo.RedirectStandardOutput = true;
      p.StartInfo.FileName = "Write500Lines.exe";
      p.Start();
      // Do not wait for the child process to exit before
      // reading to the end of its redirected stream.
      // p.WaitForExit();
      // Read the output stream first and then wait.
      string output = p.StandardOutput.ReadToEnd();
      p.WaitForExit();
      

      【讨论】:

      • 好吧,这会使窗口出现——但那是空的,我的结果字符串也是空的。这真是令人困惑
      • 你检查过标准错误吗:output = p.StandardError.ReadToEnd();
      【解决方案4】:

      摆脱循环并将对ReadToEnd的调用移动到cproc_Exited

      【讨论】:

      • 坏主意:如果它试图写入大量没有读取的数据,进程将挂起。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多