2012-02-29 32 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");に電話すると、「よろしいですか?」というメッセージが表示されますが、inputWriter.Write("y");と「y」と表示されてもコンソールでエコーバックされますが、何も起こりません。 私がinputWriter.WriteLine("pause");コンソールに電話をかけると、inputWriter.Write(" ");の後に、それはちょうどそうするべきです。

ここでの問題は何ですか。入力をコンソールとその中で実行されているアプリケーション(およびコマンド)の両方に正しくリダイレ​​クトするにはどうすればよいですか?

ありがとうございます。

乾杯!

答えて

2

これは興味深い問題です。これは、win32コマンド・インタープリタがセキュリティ上の理由で入力を処理する方法と関連している可能性があります。 this oneのような問題を解決したプロジェクトが2つあります(主に)。入力制限を回避するために実装する必要があるかどうかを判断するために、コードを調べることができます(実際には責任がある場合)。

私はC#で書かれた完全なコンソール交換ソリューションを見たことはないと思います。

+1

私が見たコンソール交換と最も近いと思うのは、POSHコンソールです。そして、はい、私は詳細を知らないが、コンソールプログラミングはclunkyであり、PowershellでもWindowsコンソールの仕組みのためにいくつかの制限があります。 –

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

関連する問題