2010-01-06 15 views
11

Estoy comenzando una aplicación de consola, pero cuando redirijo la salida estándar, ¡siempre obtengo nada!process.standardoutput.ReadToEnd() ¿siempre vacío?

Cuando no redirigirlo, y la haga CreateNoWindow-false, veo todo correctamente en la consola, pero cuando vuelvo a dirigir él, StandardOutput.ReadToEnd() siempre devuelve una cadena vacía.

 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(); 
     } 

El EventHandler cproc_exited simplemente establece stop a true. ¿Alguien puede explicar por qué result siempre es string.Empty?

Respuesta

7

¿Por qué estás bucleando? Una vez que se lee hasta el final, no podrá leer más datos, ¿o sí?

¿Estás seguro de que el texto se está escribiendo realmente en StandardOutput en lugar de StandardError?

(Y sí, es obvio que desea establecer RedirectStandardOutput a cierto lugar de falsa asumí que era sólo un caso de que la copia de la versión incorrecta de su código..)

EDIT: Como ya he aconsejado en los comentarios, debe leer de salida estándar y error estándar en hilos separados. Do no espere hasta que el proceso haya finalizado - esto puede terminar en un punto muerto, donde está esperando que el proceso salga, pero el proceso está bloqueando el intento de escribir en stderr/stdout porque no ha leído desde el buffer.

Como alternativa, puede suscribirse a los eventos OutputDataReceived y ErrorDataReceived, para evitar el uso de subprocesos adicionales.

+0

si la cambio a mientras {} s + = convproc.StandardOutput.ReadToEnd() (parada!); me sale un punto muerto – alex

+0

¡heey, funciona! parece que mi amigo (que creó el programa de la consola) lo estropeó. ¡escribe todo en la secuencia de error! Tendré que hablar con él, tal vez él pueda arreglar esto. Gracias por su respuesta rápida! me salvaste de estar sentado horas y horas frente a mi pc e intentando buscar un error estúpido :) – alex

+1

@alex: saca ese bucle while - no debería estar ahí.Idealmente, use hilos separados: uno para leer desde 'StandardOutput' y otro para leer desde 'StandardError'. –

6

Tiene la redirección de salida estándar deshabilitada. Intente cambiar

cproc.StartInfo.RedirectStandardOutput = false; 

en

cproc.StartInfo.RedirectStandardOutput = true; 

¿El siguiente ejemplo de MSDN trabajo para usted?

// 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

todavía no cambia nada – alex

+0

bien esto hace que aparezca la ventana, pero eso es vacía, y mi cadena de resultados está vacío, también. esto es realmente confuso – alex

+0

¿Ha comprobado el error estándar: 'output = p.StandardError.ReadToEnd();'? –

-1

Deshágase del bucle y desplace la llamada al ReadToEnd al cproc_Exited.

+0

Mala idea: el proceso se bloqueará si intenta escribir muchos datos que nada está leyendo. –

15

La mejor manera para ello es redirigir la salida y esperar a que los acontecimientos:

// 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

Útil. Gracias. –

Cuestiones relacionadas