重定向控制台应用程序的标准输入

我有一个控制台应用程序,我试图通过重定向过程的标准输入流自动化。 在打开应用程序后的手动模式下,它等待用户输入,如下所示, 在此处输入图像描述

我使用重定向的标准输入流创建了该过程。代码片段如下,

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

但是创建这样的过程会产生如下所示的无限循环, 在此处输入图像描述

这就像我将Enter键命令连续发送到过程输入流。 谁能指出我在这里做错了什么?

同样,标准输出流重定向在制作后也不起作用

newProcess.StartInfo.RedirectStandardOutput = true

但我可以解决这个问题。

标准流的重定向是否适用于所有控制台应用程序,或者是否有任何exception?

这是我写的一个类,以处理这种东西。 随意使用它。 它的目的是启动一个控制台应用程序并与之“交谈”。 它也能够接收输出。 祝好运。

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

按照上一个答案,我只是添加SubArray的扩展方法,以防万一将这个类添加到你的代码中,它没有嵌套在任何类中 (代码在注释中看起来不可读,所以我在这里添加了它)

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