控制台输入重定向
本文关键字:重定向 输入 控制台 | 更新日期: 2023-09-27 18:26:26
我正在编写一个windows应用程序,该应用程序通过将cmd.exe的输入和输出重定向到文本框来模拟控制台。起始代码如下:
StreamWriter inputWriter;
StreamReader outputReader;
StreamReader errorReader;
Process proc = new Process();
byte[] outputBuffer = new byte[1024];
byte[] errorBuffer = new byte[1024];
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = "/Q";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.ErrorDialog = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
inputWriter = proc.StandardInput;
outputReader = proc.StandardOutput;
errorReader = proc.StandardError;
outputReader.BaseStream.BeginRead(outputBuffer, 0, outputBuffer.Length, ShowOutput, null);
errorReader.BaseStream.BeginRead(errorBuffer, 0, errorBuffer.Length, ShowError, null);proc.StartInfo.Arguments = "/Q";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.ErrorDialog = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
inputWriter = proc.StandardInput;
outputReader = proc.StandardOutput;
errorReader = proc.StandardError;
outputReader.BaseStream.BeginRead(outputBuffer, 0, outputBuffer.Length, ShowOutput, null);
errorReader.BaseStream.BeginRead(errorBuffer, 0, errorBuffer.Length, ShowError, null);
当我启动进程时,我可以读取控制台输出,也可以通过写入输入流向其发送命令。
当我以这种方式启动某个应用程序时,该应用程序的输出也会被重定向,一切仍然正常,但该应用程序似乎没有接收到写入输入流的数据。甚至一些控制台命令也无法接收输入。例如,如果我调用inputWriter.WriteLine("del *.log");
,我会收到"你确定吗"提示,但当我调用inputWriter.Write("y");
"y"时,控制台会回显,但没有发生任何事情,控制台会继续等待输入。如果我调用inputWriter.WriteLine("pause");
控制台会暂停,在inputWriter.Write(" ");
之后,它会像应该的那样继续。
这里的问题是什么?我如何正确地将输入重定向到控制台和在其中执行的应用程序(和命令)?
提前谢谢。
干杯!
这是一个有趣的问题,可能与win32命令解释器出于安全原因处理输入的方式有关。有几个项目(大部分)解决了这些问题,比如这个。您可能想仔细查看代码(不过是C++),试图弄清楚是否有一些技巧需要实现来绕过输入限制(如果它们确实是罪魁祸首的话)。
我想我从来没有见过用C#编写的完整控制台更换解决方案。
我已经多次这样做了。这个问题是由于您的程序是单线程的。您需要异步运行流程。这是我的一个例子。
private void exportButton_Click(object sender, EventArgs e)
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "";
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(ConsoleOutputHandler);
p.Start();
p.BeginOutputReadLine();
//p.WaitForExit();
//p.Dispose();
}
private void UpdateTextBox(String message)
{
if (consoleOutputBox.InvokeRequired)
{
UpdateConsoleWindowDelegate update = new UpdateConsoleWindowDelegate(UpdateTextBox);
consoleOutputBox.BeginInvoke(update, message);
}
else
{
consoleOutputBox.AppendText(message);
}
}
void ConsoleOutputHandler(object sendingProcess, System.Diagnostics.DataReceivedEventArgs recieved)
{
if (!String.IsNullOrEmpty(recieved.Data))
{
UpdateTextBox(recieved.Data + "'n");
}
}