How to run an exe as a process and read its input multiple times and respond to it multiple times c#?

307 Views Asked by At

I am running an exe by the process like

public static void executeProcessInCMD(string methodArguments)
        {
            try
            {
                methodArguments = "\"" + methodArguments + "\"";
                Process p = new Process();
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.WindowStyle = ProcessWindowStyle.Hidden;
                p.EnableRaisingEvents = true;
                startInfo.FileName = "cmd.exe";
                startInfo.UseShellExecute = false;
                startInfo.Arguments = "/c " + methodArguments;
                startInfo.RedirectStandardError = true;
                startInfo.RedirectStandardOutput = true;
                startInfo.RedirectStandardInput = true;
                startInfo.CreateNoWindow = true;
                startInfo.Verb = "runas";
                p.StartInfo = startInfo;
                p.Start();
                p.WaitForExit();
                string error = p.StandardError.ReadToEnd();
                if (error != string.Empty)
                {
                    Console.WriteLine("error in executing cmd process : " + error);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

When you start this exe it asks for input, when you provide it an input it does some process and again asks for another input from the user, then the user has to provide another input, and so on.

I can not figure out how to do this. Like I can read the standard output from the exe one time and give the inputs as arguments to it. But how do I do it multiple times as I do from cmd?

1

There are 1 best solutions below

0
jeanluc162 On BEST ANSWER

You need to redirect the Processes Standard Output, Error and Input and attach to some events so you can interact with it programatically:

using (var process = new Process())
{
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.RedirectStandardOutput = true;
    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.RedirectStandardInput = true;
    process.StartInfo.Arguments = "-yourArgument=YourValue"; //optional
    process.StartInfo.FileName = "pathToYourExecutable.exe";
    try
    {
        process.OutputDataReceived += (sender, e) =>
        {
            //Capture Process stdout here
            if (e.Data == null)
            {
                outputWaitHandle.Set();
            }
            else
            {
                
                //Detect what the program wants
                switch(e.Data)
                {
                    case "Please Input Number":
                        //Provide an input
                        process.StandardInput.WriteLine("99");
                        break;
                    case "Please Input String":
                        process.StandardInput.WriteLine("Test");
                        break;
                    default:
                        //Emulate just pressing [ENTER]
                        process.StandardInput.WriteLine("");
                        break;
                }
            }
        };
        process.ErrorDataReceived += (sender, e) =>
        {
            //Capture process stderr here
            if (e.Data == null)
            {
                errorWaitHandle.Set();
            }
            else
            {
                

                //react to output by providing an input
                process.StandardInput.WriteLine("No");
            }
        };

        if (process.Start())
        {
            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            process.WaitForExit();
        }
        else
        {
            //process failed to start
        }
    }
    catch(Exception ex)
    {
        //Handle Exceptions
    }
    finally
    {
        //Cleanup
        outputWaitHandle.WaitOne(15000);
        errorWaitHandle.WaitOne(15000);
    }
}

You can find further information on the StandardInput here and on the StandardOutput here.