C#处理呼叫,与标准输入和标准输出交互

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

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

这是我正在调用以执行此测试的批处理文件:

@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#片段:

  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 

有没有办法可以观察标准输出以便相应地提示和响应它?

您的主要问题是您使用sr.ReadLine()流阅读器这是一个问题,因为密码提示会停止,直到用户输入新行(键入密码后按Enter键)。

所以你需要一次读取流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; } 

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

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