我有一个单击按钮执行命令。该命令可能会提示某些标准输入,我需要响应该输入,问题是程序运行的方式可能每天都不同,所以我需要解释标准输出并相应地重定向标准输入。
我有这段简单的代码,它逐行读取标准输出,当它看到密码提示时,它会发送标准输入,但程序只是挂起,因为它从未看到密码的提示,但是当我运行批处理文件时,密码提示符就在那里。
这是我正在调用以执行此测试的批处理文件:
@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
有没有办法可以观察标准输出以便相应地提示和反应?
答案 0 :(得分:3)
您的主要问题是您使用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;
}
答案 1 :(得分:0)
使用流程类,您可以直接运行批处理文件。标准I / O可能无法通过,因为它必须首先通过cmd
proc.StartInfo.FileName = "test4.bat";
proc.StartInfo.Arguments = "";