2010-01-06 101 views
11

我正在启动一个控制台应用程序,但是当我重定向标准输出时,我总是一无所得!process.standardoutput.ReadToEnd()总是空的?

当我不重定向它,并设置CreateNoWindowfalse,我在控制台中正确地看到的一切,但是当我把它重定向,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只是设置stoptrue。有人可以解释为什么result总是string.Empty

回答

7

为什么你循环?一旦它被读到最后,它将无法读取更多的数据,是吗?

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

(是的,很显然你要设置RedirectStandardOutput为真而不是假的我以为那只是你复制你的代码的错误版本的情况下。)

编辑:正如我所建议评论,你应该从单独的线程中读取标准输出和标准错误。做而不是等到进程退出 - 这可能会导致死锁,在此等待进程退出,但进程阻止尝试写入标准错误/标准输出,因为您尚未读取缓冲。

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

+0

。 我得到了一个死锁 – alex 2010-01-06 11:33:15

+0

heey,它的工作原理!看起来像我的朋友(谁做了控制台程序)搞砸了!它将所有内容写入错误流!我得和他谈谈,也许他可以解决这个问题。感谢您的快速回答!你从我的电脑前几小时和几个小时的时间里救了我,试图寻找一个愚蠢的错误:) – alex 2010-01-06 11:44:45

+1

@alex:取出while循环 - 它不应该在那里。理想情况下,使用不同的线程 - 一个从'StandardOutput'读取,一个从'StandardError'读取。 – 2010-01-06 11:59:51

6

您已将标准禁止重定向。尝试改变

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(); 
+0

仍然改变不了什么 – alex 2010-01-06 11:28:26

+0

以及这使得窗口出现,但多数民众赞成空的,我的结果字符串是空的,太。 这真的令人困惑 – alex 2010-01-06 11:39:07

+0

你检查了标准错误:'output = p.StandardError.ReadToEnd();'? (!stop) { } s + = convproc.StandardOutput.ReadToEnd();如果我将其更改为 ,则为 – 2010-01-06 11:41:20

-1

摆脱环路并将电话转到ReadToEndcproc_Exited。此

+0

坏主意:如果它试图写入大量数据的其中没有什么是阅读过程中会挂起。 – 2010-01-06 12:32:38

15

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

// some of the flags are not 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_OutputDataReceived; 
    process.Exited += process_Exited; 
    process.Start(); 
    process.BeginErrorReadLine(); 
    process.BeginOutputReadLine(); 

    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; 
    } 
+0

有用。谢谢。 – 2011-04-28 11:30:01