Разрешение перенаправления StandardInput приложения C # при выполнении «Console.ReadKey» - PullRequest
3 голосов
/ 30 июля 2011

У меня есть 2 приложения, A & B.

  • A вызывает B внутри процесса.
  • B делает некоторые вещи, такие как Console.WriteLine и Console.ReadLine
  • Благодаря этой статье MSDN мне удается каким-то образом перенаправить вывод B и подать его также.

  • ЧтоМне не удается сделать , это заставить работать * B функцию Console.ReadKey .Я сделал блок try catch для этой функции и получил следующее сообщение об ошибке:

Невозможно прочитать ключи, когда приложение не имеет консоли или когда ввод с консолибыл перенаправлен из файла.Попробуйте Console.Read

Дело в том, что мне нужно использовать Console.ReadKey, поэтому мне нужно найти способ заставить его работать ... Есть идеи?

Вот полезные части кода A


В основной функции:

Process P2 = new Process();
P2.StartInfo.FileName = Environment.CurrentDirectory + "\\Main2.exe";
P2.StartInfo.UseShellExecute = false;
P2.StartInfo.RedirectStandardOutput = true;
P2.OutputDataReceived += new DataReceivedEventHandler(WriteOutput);
P2.StartInfo.RedirectStandardInput = true;
P2.Start();
StreamWriter ExeInput = P2.StandardInput;
P2.BeginOutputReadLine();
ConsoleKeyInfo KeyPressed;
do 
{
    KeyPressed = Console.ReadKey();
    if(KeyPressed.Key == ConsoleKey.Enter)
    {
        Console.WriteLine ();
        ExeInput.Write("\n");
    }
    else
        ExeInput.Write(KeyPressed.KeyChar);
} while (!P2.HasExited);

Обработчик для выходных данных получен:

private static void WriteOutput(object sendingProcess, DataReceivedEventArgs outLine)
{
    if (!String.IsNullOrEmpty(outLine.Data))

    {
        Console.WriteLine(outLine.Data);
    }
}

1 Ответ

5 голосов
/ 30 июля 2011

Я не знаю ни одного способа использования ReadKey() при перенаправлении StdIn / StdOut консольной программы. Кроме того, для чтения и записи из дочернего процесса необходимо убедиться, что вы используете Console.Out.Write() / Console.In.Read(), чтобы исключить исключение из дочернего процесса, поскольку в нем отсутствует консольное окно.

Вы можете использовать Convert.ToChar(ExeOutput.Read()) для преобразования ввода в действительное KeyChar, имитируя поведение ReadKey() Также имейте в виду, Синхронные против Асинхронных операций чтения / записи. Если вы используете BeginOutputReadLine() и читаете поток асинхронно, ваше условие while для P2.HasExited может стать истинным, прежде чем вы прочитаете все клавиши ввода при использовании ExeOutput.Read()

        .....
        P2.Start();
        StreamWriter ExeInput = P2.StandardInput;
        StreamReader ExeOutput = P2.StandardOutput;
        do
        {
            var k = P2.StandardOutput.Read();
            var key = Convert.ToChar(k);
            if (key == Convert.ToChar(ConsoleKey.Enter))
            {
                Console.WriteLine();
                ExeInput.Write("\n");
            }
            else
                ExeInput.Write(key);
        } while (!P2.HasExited);
        ....

К счастью, потоки будут буферизованы, если процесс завершился до того, как вы прочитали каждую строку, поэтому вы можете рассмотреть возможность изменения условия на while(!P2.HasExited && !P2.StandardOutput.EndOfStream), если это соответствует тому, что вы пытаетесь выполнить.

...