控制台应用程序提示输入

4
我正在尝试使用StandardInput和StandardOutput来封装控制台应用程序。但当控制台应用程序需要输入密码等内容时,我会遇到困难。
我想从StandardOutput中读取信息,提示用户输入,并将用户的输入写回控制台应用程序的StandardInput中。看起来很简单,以下是我目前的代码:
Process process = new Process()
{
    StartInfo =
    {
        FileName = "bin\\vpnc.exe",
        Arguments = "--no-detach --debug 0",
        CreateNoWindow = true,
        UseShellExecute = false,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
    }
};

process.OutputDataReceived += (s, args) => 
{
    textBlock1.Dispatcher.Invoke(new Action(() =>
    {
        textBlock1.Text += args.Data;
    }));
};
process.Start();
process.BeginOutputReadLine();

问题在于 BeginOutputReadLine() 只是在等待换行符。 在这种情况下,它只会一直等待,因为没有要读取的行...控制台应用程序已经输出了没有换行符的文本并正在等待输入。巧合的是,当我手动终止进程时,事件会触发并且我会收到文本。

有没有办法判断进程是否正在等待标准输入?或者我是否错过了一个完全明显的方法来实现目标?

4个回答

1

process.StandardOutput.BaseStream.BeginRead(...) 可以替代 readline,它不会等待行结束,但您需要知道什么终止输出,以便在下一块数据到达之前停止等待。


会不会是 StandardOutput.BaseStream.BeginRead(...)?我在 StandardOutput 上没有看到这个方法,它是一个 StreamReader。直接从 StandardOutput.BaseStream 读取会影响读取器吗? - John Clayton
@John 我的错,抱歉,是的,应该是 BaseStream.BeginRead。 - Rune FS

1

当控制台等待输入时,ReadToEnd也会挂起。 - John Clayton
ReadToEnd通常只建议与WaitForExit一起使用,因为在此之前可能没有结束。问题是,您可能会在流被读取之前结束应用程序,从而使ReadToEnd和WaitForExit成为潜在的死锁。 - Rune FS

0
你需要使用同步读取方法并自行处理任何必要的线程。下面的代码不会告诉你输入是什么,但你将能够检测到提示被显示。
        char[] b = new char[1024];
        while (!process.HasExited) {
            int c = process.StandardOutput.Read(b, 0, b.Length);
            context.Response.Write(b, 0, c);
            Thread.Sleep(100);
        }

0

正如Rune所说,您可以直接访问进程的输出流(process.StandardOutput),并从那里读取(如果您不想等待换行符输入到控制台应用程序中),但这意味着您需要定期检查新数据。

要与应用程序交互,您只需写入进程的StandardInput(创建一个写入进程.StandardInput的StreamWriter)。

在MSDN文档(http://msdn.microsoft.com/en-us/library/system.diagnostics.process.beginoutputreadline.aspx)中有一个很好的写入示例。

希望这可以帮助到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接