如何检测不同进程中的批处理文件何时提示输入?

时间:2016-02-25 14:47:29

标签: c# batch-file process

我想要使用自动输入运行一系列批处理文件。

他们在执行中至少有一个点,他们暂停并要求输入。通过:

set /p FOO=Please enter value for FOO:

或只是一个简单的

pause

我的问题是,如果我重定向输入和输出流,提示只会在我已经发送输入后到达输出流。因此,我必须在提示之前听取输出以触发我的预设响应。

摆脱了两个脚本。然而另一个在第一个提示之前没有任何输出。

我尝试过使用Process.WaitForInputIdle,但会抛出一个Exception,说明该进程没有消息循环。

到目前为止我的代码:

    private void Foo()
        var p = StartElevatedProcess("script.bat", true /*redirect*/);
        p.OutputDataReceived += p_OutputDataReceived;
        p.BeginOutputReadLine();
        p.WaitForExit();
    }

    void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data == null) return;
        Console.WriteLine(e.Data);

        if (e.Data.StartsWith("Install complete"))
        {
            ((Process)sender).StandardInput.WriteLine();
        }
    }

1 个答案:

答案 0 :(得分:0)

我终于明白了。异步模式可能不支持此功能,但StandardOutput上的同步读取会支持!

        Process p = StartElevatedProcess(
            "script.bat",
            true);
        do
        {
            char[] buff = new char[1000];
            int i = p.StandardOutput.Read(buff, 0, buff.Length);
            string output = new String(buff, 0, i);
            if (output.Contains("Please enter value for FOO:"))
            {
                Console.WriteLine(output);
                p.StandardInput.WriteLine("Foo value");
            }
            else if (output.Contains("Please enter value for BAR:"))
            {
                Console.WriteLine(output);
                p.StandardInput.WriteLine("Bar value");
            }
            else if (output.Contains(". . ."))
            {
                // Handle "Hit any key to continue"
                p.StandardInput.WriteLine();
            }
            else
            {
                Console.WriteLine(output);
            }
            Thread.Sleep(100);
        } while (!p.HasExited);

这可能不太理想。线条撕裂可能会导致脚本产生大量输出或运行很长时间。但希望这可以节省别人的时间来解决这个问题。