Redirigir la entrada estándar de la aplicación de la consola

Tengo una aplicación de consola que estoy tratando de automatizar mediante la redirección del flujo de entrada estándar del proceso. En modo manual después de abrir la aplicación, espera la entrada del usuario como a continuación, enter image description here

Creé el proceso con la secuencia de entrada estándar redirigida. El fragmento de código es el siguiente,

Process newProcess = new Process(); newProcess.StartInfo.FileName = exeName; newProcess.StartInfo.Arguments = argsLine; newProcess.StartInfo.UseShellExecute = false; newProcess.StartInfo.RedirectStandardOutput = false ; newProcess.StartInfo.CreateNoWindow = false; newProcess.StartInfo.RedirectStandardInput = true; newProcess.Start(); 

Pero crear un proceso como este da un ciclo infinito que se muestra a continuación, enter image description here

Es como si estuviera enviando el comando de tecla Enter continuamente al flujo de entrada del proceso. ¿Alguien puede señalarme qué estoy haciendo mal aquí?

Del mismo modo, la redirección de flujo de salida estándar tampoco funciona después de hacer

newProcess.StartInfo.RedirectStandardOutput = true

Pero puedo manejar eso.

¿El redireccionamiento de las transmisiones estándar funciona con todas las aplicaciones de la consola o existe alguna excepción?

Aquí hay una clase que he escrito para manejar ese tipo de cosas. Sientase libre de usarlo. Su propósito es iniciar una aplicación de consola y “hablar” con ella. También tiene la capacidad de recibir resultados. Buena suerte.

 using System; using System.Diagnostics; using System.Text; using System.Threading; using System.Threading.Tasks; public class ConsoleAppManager { private readonly string appName; private readonly Process process = new Process(); private readonly object theLock = new object(); private SynchronizationContext context; private string pendingWriteData; public ConsoleAppManager(string appName) { this.appName = appName; this.process.StartInfo.FileName = this.appName; this.process.StartInfo.RedirectStandardError = true; this.process.StartInfo.StandardErrorEncoding = Encoding.UTF8; this.process.StartInfo.RedirectStandardInput = true; this.process.StartInfo.RedirectStandardOutput = true; this.process.EnableRaisingEvents = true; this.process.StartInfo.CreateNoWindow = true; this.process.StartInfo.UseShellExecute = false; this.process.StartInfo.StandardOutputEncoding = Encoding.UTF8; this.process.Exited += this.ProcessOnExited; } public event EventHandler ErrorTextReceived; public event EventHandler ProcessExited; public event EventHandler StandartTextReceived; public int ExitCode { get { return this.process.ExitCode; } } public bool Running { get; private set; } public void ExecuteAsync(params string[] args) { if (this.Running) { throw new InvalidOperationException( "Process is still Running. Please wait for the process to complete."); } string arguments = string.Join(" ", args); this.process.StartInfo.Arguments = arguments; this.context = SynchronizationContext.Current; this.process.Start(); this.Running = true; new Task(this.ReadOutputAsync).Start(); new Task(this.WriteInputTask).Start(); new Task(this.ReadOutputErrorAsync).Start(); } public void Write(string data) { if (data == null) { return; } lock (this.theLock) { this.pendingWriteData = data; } } public void WriteLine(string data) { this.Write(data + Environment.NewLine); } protected virtual void OnErrorTextReceived(string e) { EventHandler handler = this.ErrorTextReceived; if (handler != null) { if (this.context != null) { this.context.Post(delegate { handler(this, e); }, null); } else { handler(this, e); } } } protected virtual void OnProcessExited() { EventHandler handler = this.ProcessExited; if (handler != null) { handler(this, EventArgs.Empty); } } protected virtual void OnStandartTextReceived(string e) { EventHandler handler = this.StandartTextReceived; if (handler != null) { if (this.context != null) { this.context.Post(delegate { handler(this, e); }, null); } else { handler(this, e); } } } private void ProcessOnExited(object sender, EventArgs eventArgs) { this.OnProcessExited(); } private async void ReadOutputAsync() { var standart = new StringBuilder(); var buff = new char[1024]; int length; while (this.process.HasExited == false) { standart.Clear(); length = await this.process.StandardOutput.ReadAsync(buff, 0, buff.Length); standart.Append(buff.SubArray(0, length)); this.OnStandartTextReceived(standart.ToString()); Thread.Sleep(1); } this.Running = false; } private async void ReadOutputErrorAsync() { var sb = new StringBuilder(); do { sb.Clear(); var buff = new char[1024]; int length = await this.process.StandardError.ReadAsync(buff, 0, buff.Length); sb.Append(buff.SubArray(0, length)); this.OnErrorTextReceived(sb.ToString()); Thread.Sleep(1); } while (this.process.HasExited == false); } private async void WriteInputTask() { while (this.process.HasExited == false) { Thread.Sleep(1); if (this.pendingWriteData != null) { await this.process.StandardInput.WriteLineAsync(this.pendingWriteData); await this.process.StandardInput.FlushAsync(); lock (this.theLock) { this.pendingWriteData = null; } } } } } 

Siguiendo la respuesta anterior, solo agregaré el método de extensión de SubArray, por si agregas esta clase a tu código donde no está nested dentro de ninguna clase (el código no parecía legible en un comentario, así que lo agregué aquí)

 public static class CharArrayExtensions { public static char[] SubArray(this char[] input,int startIndex, int length) { List result= new List(); for (int i = startIndex; i < length; i++) { result.Add(input[i]); } return result.ToArray(); } }