GianT971
GianT971

Reputation: 4523

Allowing redirection of StandardInput of a C# application when doing "Console.ReadKey"

I have 2 applications, A & B.

Cannot read keys when either application does not have a console, or when console input has been redirected from a file. Try Console.Read

The fact is, I have to use Console.ReadKey, so I need to find a way to make it work...Any idea?

Here are the useful parts of the code of A


In the Main function:

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);

The handler for outputdatareceived:

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

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

Upvotes: 5

Views: 6340

Answers (1)

Christopher Currens
Christopher Currens

Reputation: 30695

I'm not aware of any way of being able to use ReadKey() when redirecting the StdIn/StdOut of a console program. Furthermore, in order to read and write from the child process, you need to make sure you're using Console.Out.Write()/Console.In.Read() to prevent exceptions from being thrown from the child process, because it is lacking a console window.

You can use Convert.ToChar(ExeOutput.Read()) to convert the input to a valid KeyChar, mimicing the behavior of ReadKey() Also keep in mind Synchronous vs Asynchronous reads/writes. If you use BeginOutputReadLine() and read the stream Asynchronously, your while condition of P2.HasExited may become true before you read all of the input keys when using 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);
        ....

Fortunately, the streams will be buffered if the process has exited before you've read every line, so you may consider changing the condition to while(!P2.HasExited && !P2.StandardOutput.EndOfStream) if that fits what you're trying to accomplish.

Upvotes: 7

Related Questions