【问题标题】:C# Process Call, Interact with Standard Input and Standard OutputC#进程调用,与标准输入和标准输出交互
【发布时间】:2013-11-12 06:31:17
【问题描述】:

我点击了一个按钮来执行命令。该命令可能会提示一些标准输入,我需要响应该输入,问题是程序运行的方式可能每天都不同,所以我需要解释标准输出并相应地重定向标准输入。

我有一段简单的代码,它逐行读取标准输出,当它看到密码提示时,它会发送标准输入,但是程序只是挂起,因为它从来没有看到密码提示,但是当我运行批处理文件时,密码提示就在那里。

这是我为执行此测试而调用的批处理文件:

@echo off
echo This is a test of a prompt
echo At the prompt, Enter a response
set /P p1=Enter the Password: 
echo you entered "%p1%"

这是从命令行运行时该批处理文件的输出:

C:\Projects\SPP\MOSSTester\SPPTester\bin\Debug>test4.bat
This is a test of a prompt
At the prompt, Enter a response
Enter the Password: Test1
you entered "Test1"

这是我用来调用挂起的批处理文件的 C# sn-p:

    var proc = new Process();
    proc.StartInfo.FileName = "cmd.exe";
    proc.StartInfo.Arguments = "/c test4.bat";
    proc.StartInfo.RedirectStandardOutput = true;
    proc.StartInfo.RedirectStandardError = true;
    proc.StartInfo.RedirectStandardInput = true;
    proc.StartInfo.UseShellExecute = false;
    proc.StartInfo.CreateNoWindow = true;
    proc.Start();
    //read the standard output and look for prompt for password
    StreamReader sr = proc.StandardOutput;
    while (!sr.EndOfStream)
    {
        string line = sr.ReadLine();
        Debug.WriteLine(line);
        if (line.Contains("Password"))
        {
            Debug.WriteLine("Password Prompt Found, Entering Password");
            proc.StandardInput.WriteLine("thepassword");
        }
    }
    sr.Close();
    proc.WaitForExit();

这是我看到的调试标准输出,注意我从来没有看到密码提示,这是为什么?它只是挂起?

This is a test of a prompt
At the prompt, Enter a response

有没有办法可以观察标准输出以进行提示并做出相应的反应?

【问题讨论】:

    标签: c# .net batch-file process


    【解决方案1】:

    您的主要问题是您正在使用sr.ReadLine() 通过流阅读器工作,这是一个问题,因为密码提示会暂停,直到用户输入新行(输入密码后按回车键)。

    因此您需要一次读取流 1 个字符。此示例应该可以帮助您入门。

    while (!sr.EndOfStream)
    {
        var inputChar = (char)sr.Read();
        input.Append(inputChar);
        if (StringBuilderEndsWith(input, Environment.NewLine))
        {
            var line = input.ToString();
            input = new StringBuilder();
            Debug.WriteLine(line);
        }
        else if (StringBuilderEndsWith(input, "Password:"))
        {
            Debug.WriteLine("Password Prompt Found, Entering Password");
            proc.StandardInput.WriteLine("thepassword");
            var line = input.ToString();
            input = new StringBuilder();
            Debug.WriteLine(line);
        }
    }
    
    private static bool StringBuilderEndsWith(StringBuilder haystack, string needle)
    {
        var needleLength = needle.Length - 1;
        var haystackLength = haystack.Length - 1;
        for (int i = 0; i < needleLength; i++)
        {
            if (haystack[haystackLength - i] != needle[needleLength - i])
            {
                return false;
            }
        }
        return true;
    }
    

    【讨论】:

    • 有趣,我之前试过逐字阅读,但也没有运气,让我试试这个方法,然后回复你,这合乎逻辑!
    • 非常好,刚刚测试过,这段代码非常适合我正在做的事情,非常感谢!
    【解决方案2】:

    使用进程类,您可以直接运行批处理文件。标准 I/O 可能无法通过,因为它必须先通过 cmd

    proc.StartInfo.FileName = "test4.bat";
    proc.StartInfo.Arguments = "";
    

    【讨论】:

      猜你喜欢
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      • 2014-07-31
      • 2021-10-20
      相关资源
      最近更新 更多