2012-02-29 99 views
1

我写的是通过重定向输入和CMD.EXE的输出到一个文本框模拟控制台Windows应用程序。起始代码如下:控制台重定向输入

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");,我会收到“Are you sure”提示,但当我拨打inputWriter.Write("y");时,控制台会回显“y”,但没有任何反应,控制台将继续等待输入。 如果我打电话inputWriter.WriteLine("pause");控制台暂停,并且在inputWriter.Write(" ");之后它继续。

这里有什么问题,我该如何正确输入重定向到控制台和正在其内执行的应用程序(命令)两者兼而有之?

在此先感谢。

干杯!

回答

2

这是一个有趣的问题,它可能涉及到的win32命令解释器会将输入出于安全考虑的方式。有几个项目已经解决了问题(主要是),如this one。您可能希望查看代码(它是C++),试图弄清楚是否有必要实施的技巧来解决输入限制(如果它们确实是责备)。

我不认为我见过用C#编写一个完整的控制台替代解决方案。

+1

最近想到的控制台替换我见过的是POSH控制台。是的,我不知道细节,但控制台编程是笨重的,即使Powershell有一些限制,因为Windows控制台的工作方式。 – 2012-02-29 21:29:53

1

我曾在多个场合这样做。这个问题是由于你的程序是单线程的。您需要运行asyc进程。这是我的一个挑战。

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

其实我在输出流上使用BeginRead做了id异步。写入输入流会导致控制台(或控制台中运行的程序)等待输入时的问题。 我可以运行诸如dir,cd等命令,但是一旦需要提示(例如y/n),控制台就不会响应写入输入流的字符。 似乎我必须找到一个由控制台执行的进程(如果有的话),然后写入该进程的输入流...... – 0wl 2012-02-29 23:07:13

相关问题