时间:2011-07-30 02:02:01

标签: c# .net redirect input console

我有两个应用程序,A&乙

  • A在流程中调用B。
  • B做一些像Console.WriteLine和Console.ReadLine
  • 这样的东西
  • 感谢这个MSDN Article,我设法以某种方式重定向B的输出并提供其输入。

  • 我无法做的,就是在B工作中使用 Console.ReadKey 功能。我试了一下这个函数的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);

outputdatareceived的处理程序:

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

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

1 个答案:

答案 0 :(得分:5)

在重定向控制台程序的StdIn / StdOut时,我不知道有任何方法可以使用ReadKey()。此外,为了从子进程读取和写入,您需要确保使用Console.Out.Write() / Console.In.Read()来防止异常从子进程中抛出,因为它缺少控制台窗口。

您可以使用Convert.ToChar(ExeOutput.Read())将输入转换为有效的KeyChar,模仿ReadKey()的行为。还要记住同步和异步读/写。如果使用BeginOutputReadLine()并以异步方式读取流,则在使用ExeOutput.Read()

时读取所有输入键之前,P2.HasExited的while条件可能会成立
        .....
        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)