Перенаправление ввода с консоли - PullRequest
1 голос
/ 01 марта 2012

Я пишу приложение для 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(" "); она продолжается так же, как и должна.

В чем здесь проблема и как я могу правильно перенаправить ввод как на консоль, так и на приложение (и команду)что выполняется внутри него?

Заранее спасибо.

Приветствия!

Ответы [ 2 ]

2 голосов
/ 01 марта 2012

Это интересная проблема, она может быть связана с тем, как интерпретатор команд win32 обрабатывает ввод по соображениям безопасности.Есть пара проектов, которые решили проблемы (в основном), такие как этот .Возможно, вы захотите просмотреть код (хотя это C ++), чтобы попытаться выяснить, есть ли уловки, которые нужно реализовать, чтобы обойти ограничения ввода (если они действительно виноваты).

Я не знаюЯ думаю, что я когда-либо видел полное решение для замены консоли, написанное на C #.

1 голос
/ 01 марта 2012

Я делал это несколько раз.Проблема вызвана тем, что ваша программа однопоточна.Вам нужно запустить процесс 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");
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...