问题描述
我有2个应用程序,即A& B.
- A调用流程中的B.
- B做一些类似Console.WriteLine和Console.ReadLine的事情
-
感谢这篇 MSDN文章,我设法以某种方式重定向B的输出并也提供其输入.
-
我没办法做,是要在B工作中具有 Console.ReadKey 功能.我在该函数周围做了一个try catch块,并收到以下错误消息:
事实是,我必须使用Console.ReadKey,所以我需要找到一种使其工作的方式...知道吗?
以下是A代码的有用部分
在Main函数中:
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);
已收到outputdata的处理程序:
private static void WriteOutput(object sendingProcess, DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
{
Console.WriteLine(outLine.Data);
}
}
将控制台程序的StdIn/StdOut重定向时,我不知道能够使用ReadKey()
的任何方式.此外,为了从子进程中读写,您需要确保使用Console.Out.Write()
/Console.In.Read()
来防止子进程抛出异常,因为它缺少控制台窗口./Console.In.Read()
>
您可以使用Convert.ToChar(ExeOutput.Read())
将输入转换为有效的KeyChar
,模仿ReadKey()
的行为.还要记住,同步读取与异步读取/写入.如果使用BeginOutputReadLine()
并异步读取流,则在使用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)
.
I have 2 applications, A & B.
- A calls B within a Process.
- B do some stuffs like Console.WriteLine and Console.ReadLine
Thanks to this MSDN Article, I manage somehow to redirect the output of B and to feed its input as well.
What I don't manage to do, is to have the Console.ReadKey function in B work. I made a try catch block arround this function and I got this error message:
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);
}
}
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.
这篇关于当执行"Console.ReadKey"时,允许重定向C#应用程序的StandardInput.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!