How to send input to the console as if the user is typing?

12,935

Solution 1

This sounds like a task for SendKeys(). It's not C#, but VBScript, but nontheless - you asked for some way of automating it:

Set Shell = CreateObject("WScript.Shell")

Shell.Run "cmd.exe /k title RemoteControlShell"
WScript.Sleep 250

Shell.AppActivate "RemoteControlShell"
WScript.Sleep 250

Shell.SendKeys "dir{ENTER}"

Solution 2

I have figured out how to send the input to the console. I used what Jon Skeet said. I am not 100% sure this is the correct way to implement this.

If there are any comments on to make this better I would love to here. I did this just to see if I could figure it out.

Here is the program I stared that waited for input form the user

class Program
{
    static void Main(string[] args)
    {
        // This is needed to wait for the other process to wire up.
        System.Threading.Thread.Sleep(2000);

        Console.WriteLine("Enter Pharse: ");

        string pharse = Console.ReadLine();

        Console.WriteLine("The password is '{0}'", pharse);


        Console.WriteLine("Press any key to exit. . .");
        string lastLine = Console.ReadLine();

        Console.WriteLine("Last Line is: '{0}'", lastLine);
    }
}

This is the console app writing to the other one

class Program
{
    static void Main(string[] args)
    {
        // Find the path of the Console to start
        string readFilePath = System.IO.Path.GetFullPath(@"..\..\..\ReadingConsole\bin\Debug\ReadingConsole.exe");

        ProcessStartInfo startInfo = new ProcessStartInfo(readFilePath);

        startInfo.RedirectStandardOutput = true;
        startInfo.RedirectStandardInput = true;
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
        startInfo.CreateNoWindow = true;
        startInfo.UseShellExecute = false;

        Process readProcess = new Process();
        readProcess.StartInfo = startInfo;

        // This is the key to send data to the server that I found
        readProcess.OutputDataReceived += new DataReceivedEventHandler(readProcess_OutputDataReceived);

        // Start the process
        readProcess.Start();

        readProcess.BeginOutputReadLine();

        // Wait for other process to spin up
        System.Threading.Thread.Sleep(5000);

        // Send Hello World
        readProcess.StandardInput.WriteLine("Hello World");

        readProcess.StandardInput.WriteLine("Exit");

        readProcess.WaitForExit();
    }

    static void readProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        // Write what was sent in the event
        Console.WriteLine("Data Recieved at {1}: {0}", e.Data, DateTime.UtcNow.Ticks);
    }
}

Solution 3

Can you start the program (or cygwin) within your code, using ProcessStartInfo.RedirectStandardInput (and output/error) to control the data flow?

Share:
12,935
Programatt
Author by

Programatt

I am a programmer by day, and a tinkerer by night.

Updated on June 17, 2022

Comments

  • Programatt
    Programatt almost 2 years

    This is my problem. I have a program that has to run in a TTY, cygwin provides this TTY. When I redirect stdIn the program fails because it does not have a TTY. I cannot modify this program, and need some way of automating it.

    How can I grab the cmd.exe window and send it data and make it think the user is typing it?

    I'm using C#, I believe there is a way to do it with java.awt.Robot but I have to use C# for other reasons.

  • Programatt
    Programatt over 15 years
    I can start it with it. But once it get's the the point where the program has to have the TTY it fails. The program asks for a password, and modifies the TTY to hide the keystrokes. It cannot do this with a redirected stream so it fails.
  • Programatt
    Programatt over 15 years
    I was actually looking at SendKeys already. SendKey's is part of the .NET 2.0 framework so I can use it from C#. I'll see if this works.
  • Programatt
    Programatt over 15 years
    no, cygwin writes everything to the StandardErrorStream. The error is about ioclt inappropriate for the device meaning I need a real TTY for it to be used.
  • Jon Skeet
    Jon Skeet over 15 years
    Using the SendKeys class basically requires you to make the TTY active - then you just call SendKeys.Send and it sends the keystrokes.
  • Programatt
    Programatt over 15 years
    But it's not working, occasionally it will send one key, and that's it. I think I may ask another question about sendkey's if I cannot get it working soon.
  • Programatt
    Programatt over 15 years
    bash: [####: #] tcsetattr: Inappropriate ioctl for device
  • Programatt
    Programatt over 15 years
    Okay, the problem was I was losing focus, that is fixed now.
  • rogerdpack
    rogerdpack almost 9 years
    See also stackoverflow.com/questions/6838363/… for a C++ equivalent to SendKeys. When Jon Skeet said "make active" I believe he's referring to the AppActive which "brings an application's window into focus." Apparently there's no reliable way to just send messages to a window stackoverflow.com/questions/1220820/…