Link to home
Start Free TrialLog in
Avatar of JElster
JElsterFlag for United States of America

asked on

C# ProcessStart - How to automatically press the Y key

Hi.. I'm using ProcessStart to automatically run an external process. I need to press the Y key after about a second to continue the process.  The process runs in DOS and I need to 'Accept' a message.  How can I press the Y key automatically here is my existing code.  thanks

  ProcessStartInfo _psi = new ProcessStartInfo("pgp.exe");
                _psi.WorkingDirectory = "C:\";
                _psi.RedirectStandardInput = true;
                _psi.RedirectStandardOutput = true;
                _psi.RedirectStandardError = true;

                _psi.CreateNoWindow = false;

                 _psi.Arguments = " -e  test.txt  public.asc  myEmail +force  ";

                 System.Diagnostics.Process proc = System.Diagnostics.Process.Start(_psi);

                 System.IO.StreamReader output = proc.StandardOutput;

             
                 // Attach the in for writing
                 System.IO.StreamWriter sIn = proc.StandardInput;

       
                 // Write each line of the batch file to standard input
                 while (output.Peek() != -1)
                 {
                               /// Need to press the enter key after the message in dos window

                     sIn.WriteLine(output.ReadLine());
                 }
Avatar of saragani
saragani

You can try using this:

http://inputsimulator.codeplex.com/

How about;
SendKeys.Send("{Y}");
SendKeys only work with windows applications
You  redirected stdin so your can write strings to a stream and the console
will read it from std in like normal

Avatar of JElster

ASKER

What?
something like this:

sIn.WriteLine("Y");
sIn.Flush();      

Open in new window

If SendKeys.Send("{Y}") doesn't help you then try the InputSimulator.
The InputSimulator should also solve your problem.
ASKER CERTIFIED SOLUTION
Avatar of Todd Gerbert
Todd Gerbert
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You can also redirect StandardInput and not StandardOutput, wait for a second, and then write a "Y" to StandardInput - this is much simpler but has the downside that you might send the "Y" too early, and won't be able to know if something went wrong.

using System;
using System.Diagnostics;
using System.Text;
using System.Threading;

class Program
{
	static void Main(string[] args)
	{
		Process proc = new Process();
		// Run the command "del c:\temp" in a DOS window
		// This will show a confirmation prompt requiring 
		// us to send a "Y" to continue
		proc.StartInfo.FileName = "cmd.exe";
		proc.StartInfo.Arguments = @"/c del c:\temp\*";

		// Redirect standard input
		proc.StartInfo.RedirectStandardInput = true;

		// UseShellExecute must be false to redirect input
		proc.StartInfo.UseShellExecute = false;

		// Start the process
		proc.Start();

		// Wait a second
		Thread.Sleep(1000);

		// Write a "Y" to the process's input
		proc.StandardInput.WriteLine("Y");

		// Now that we've sent the confirmation "Y" wait for the process to exit
		proc.WaitForExit();

		Console.WriteLine("The process finished with ExitCode: {0}", proc.ExitCode);
		Console.Write("Press any key to exit...");
		Console.ReadKey();
	}
}

Open in new window

Avatar of JElster

ASKER

It appears I have to press ENTER after the Y.
How can I press ENTER.
thx again
Avatar of JElster

ASKER

The following does not help

  proc.StandardInput.WriteLine("Y");
                         proc.StandardInput.WriteLine();
                         proc.StandardInput.Flush();


Still requires a manual enter

????????
Post your code.
Avatar of JElster

ASKER

 ProcessStartInfo _psi = new ProcessStartInfo("pgp.exe");
                _psi.WorkingDirectory = ConfigurationSettings.AppSettings["UpLoadLocation"];
                _psi.UseShellExecute = false;
                _psi.RedirectStandardInput = true;
                _psi.RedirectStandardOutput = true;
                _psi.RedirectStandardError = true;

                _psi.CreateNoWindow = false;

                 _psi.Arguments = " -e " + _zipFile + "  MYKEY.asc  MYEMAIL   +force  ";

                 System.Diagnostics.Process proc = System.Diagnostics.Process.Start(_psi);

                 StringBuilder procOutput = new StringBuilder();

                 // Read the process's output until we see the
                 // "Are you sure?" prompt and then send a "Y"
                 while (!proc.StandardOutput.EndOfStream)
                 {
                     // Read up to 1024 characters into the char[] array "buffer"
                     char[] buffer = new char[1024];
                     proc.StandardOutput.Read(buffer, 0, buffer.Length);

                     // Append the chars we just read to the procOutput StringBuilder
                     procOutput.Append(buffer);

                     // Check if procOutput ends with "Are you sure (Y/N)?"
                     if (procOutput.ToString().Contains("(y/N)?"))
                     {
                         // If so send "Y" and exit this loop
                         proc.StandardInput.WriteLine("Y");
                         proc.StandardInput.WriteLine();
                         proc.StandardInput.Flush();
                         break;
                     }
                 }

                 // Now that we've sent the confirmation "Y" wait for the process to exit
                 proc.WaitForExit();
Does pgp.exe not have a command line to suppress confirmation prompts?  There should be a BATCHMODE option, intended specifically for this purpose...
Avatar of JElster

ASKER

I think it does... checking now.......
thx!
Maybe --force?
Avatar of JElster

ASKER

I'm doing a force and batchmode... get a Encryption error.......  

Says it skipping the Y/N but get an encryption error...
I'm not particularly familiar with PGP - are you sure the rest of the command line is correct? Are you testing it in a cmd window by hand before trying to run it in your C# code?
Avatar of JElster

ASKER

Yes.. that's exactly what I've been doing
thx
Well, if that switch doesn't work out for you I've updated the code slightly to be more accurate:

ProcessStartInfo _psi = new ProcessStartInfo("pgp.exe");
_psi.WorkingDirectory = ConfigurationSettings.AppSettings["UpLoadLocation"];
_psi.UseShellExecute = false;
_psi.RedirectStandardInput = true;
_psi.RedirectStandardOutput = true;
_psi.RedirectStandardError = true;

_psi.CreateNoWindow = false;

_psi.Arguments = " -e " + _zipFile + "  MYKEY.asc  MYEMAIL   +force  ";

System.Diagnostics.Process proc = System.Diagnostics.Process.Start(_psi);

StringBuilder procOutput = new StringBuilder();

// Read the process's output until we see the
// "Are you sure?" prompt and then send a "Y"
while (!proc.StandardOutput.EndOfStream)
{
	// Read up to 1024 characters into the char[] array "buffer"
	char[] buffer = new char[1024];
	// Store the number of characters actually read
	// (since it will undoubtedly be less than 1024)
	int charsRead = proc.StandardOutput.Read(buffer, 0, buffer.Length);

	// Append the chars we just read to the procOutput StringBuilder
	// Use "charsRead" to only append the part of the buffer[] array
	// that was filled, otherwise we'd end up appending a couple
	// characters that Read() filled followed by a bunch of nulls
	procOutput.Append(buffer, 0, charsRead);

	// Check if procOutput ends with "Are you sure (Y/N)?"
	if (procOutput.ToString().Contains("(y/N)?")) // Make sure this is actually "(y/N)?" and not "(y/N) ?"
	{
		// If so send "Y" and exit this loop
		proc.StandardInput.WriteLine("Y");
		proc.StandardInput.WriteLine();
		proc.StandardInput.Flush();
		break;
	}
}

// Now that we've sent the confirmation "Y" wait for the process to exit
proc.WaitForExit(); 

Open in new window


Making that batch mode work is your best bet, though.
...You can also omit lnes 37 & 38 in that example (the WriteLine method automatically appends a CRLF).
Avatar of JElster

ASKER

I think the issue is that I'm using an old PGP exe and the batchmode sucks...
Will try with a new PGP exe.. thanks for you help