【问题标题】:Console application prompting for input控制台应用程序提示输入
【发布时间】:2009-11-05 21:03:36
【问题描述】:

我正在尝试使用 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() 正在这样做...等待一行结束。在这种情况下,它只是坐着,坐着,再坐着,因为没有要读取的行……控制台应用程序写出了没有行尾的文本,正在等待输入。 巧合的是,当我手动终止进程时,事件触发并得到文本。

有没有办法告诉进程正在等待标准输入?还是我错过了实现目标的完全明显的方法?

【问题讨论】:

    标签: c# scripting process console


    【解决方案1】:

    除非你需要异步的东西,否则你可能想要ReadToEnd

    这里是所有StreamReader Methods的列表

    【讨论】:

    • ReadToEnd 在控制台等待输入时也会挂起。
    • ReadToEnd 通常只能与 WaitForExit 一起使用,因为在此之前您可能没有结束。问题是,尽管您最终得到了一个在读取流之前不退出的应用程序,这使得 ReadToEnd 和 WaitForExit 成为潜在的死锁
    【解决方案2】:

    process.StandardOutput.BaseStream.BeginRead(...) 是您的 readline 的潜在替代品,它不会等待行结束,但是您需要知道什么会终止输出以确定何时不开始等待下一个数据块

    【讨论】:

    • 那会是 StandardOutput.BaseStream.BeginRead(...) 吗?我在 StandardOutput 上看不到那个方法,它是一个 StreamReader。直接从 StandardOutput.BaseStream 读取会不会让读者感到困惑?
    • @John 我很抱歉,是的,那将是 BaseStream.BeginRead
    【解决方案3】:

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

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

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

    希望对你有帮助

    【讨论】:

      【解决方案4】:

      您需要使用同步读取方法并自己处理任何必要的线程。下面的代码不会告诉您需要输入,但您将能够检测到显示的提示。

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

      【讨论】:

        猜你喜欢
        • 2020-05-12
        • 1970-01-01
        • 2019-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-12
        • 1970-01-01
        • 2019-09-10
        相关资源
        最近更新 更多