0

I have a button I click that executes a command. The command may prompt for some standard input and I need to respond to that input, the problem is the way the program runs may be different from day to day so I need to interpret the standard output and redirect standard input accordingly.

I have this simple piece of code that reads the standard output line by line and when it sees a prompt for password, it'll send standard input, however the program just hangs since it never sees the prompt for the password, but when I run the batch file the password prompt is there.

Here is the batch file I am calling to execute this test:

@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%"

Here is the output of that batch file when run from the command line:

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"

Here is the C# snippet I am using to call the batch file that is hanging:

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

Here is the debug standard output I see, notice that I never see the prompt for the password, why is this? it just hangs?

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

Is there a way I can watch the standard output for prompting and react to it accordingly?

0

2 Answers 2

7

Your main problem is that you are working through the stream reader using sr.ReadLine() this is an issue because the prompt for a password halts until the user enters a new line (hits enter after typing the password).

So you need to read the stream 1 character at a time. This example should help you get started.

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;
    if(haystackLength < needleLength) {
        return false;
    }

    for (int i = 0; i <= needleLength; i++)
    {
        if (haystack[haystackLength - i] != needle[needleLength - i])
        {
            return false;
        }
    }
    return true;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Interesting, I had tried reading character by character before but didn't have any luck with it either, let me try with this method and get back to you, this makes logical sense!
Excellent, just tested it and this code works fantastic for what i'm doing, much appreciated!
0

With the process class you can run the batch file directly. The standard I/O might not be getting through since it has to go through cmd first

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.