¿Cómo enviar entradas a la consola como si el usuario estuviera escribiendo?
-
19-08-2019 - |
Pregunta
Este es mi problema. Tengo un programa que tiene que ejecutarse en un TTY, cygwin proporciona este TTY. Cuando redirijo stdIn, el programa falla porque no tiene un TTY. No puedo modificar este programa y necesito alguna forma de automatizarlo.
¿Cómo puedo tomar la ventana cmd.exe y enviarle datos y hacer que piense que el usuario la está escribiendo?
Estoy usando C #, creo que hay una manera de hacerlo con java.awt.Robot pero tengo que usar C # por otras razones.
Solución
Esto suena como una tarea para SendKeys ()
. No es C #, sino VBScript, pero no obstante: solicitó alguna forma de automatizarlo:
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}"
Otros consejos
He descubierto cómo enviar la entrada a la consola. Usé lo que dijo Jon Skeet. No estoy 100% seguro de que esta sea la forma correcta de implementar esto.
Si hay algún comentario para mejorar esto, me encantaría hacerlo aquí. Hice esto solo para ver si podía resolverlo.
Aquí está el programa que miré que esperaba la entrada del usuario
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);
}
}
Esta es la aplicación de consola que escribe en la otra
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);
}
}
¿Puede iniciar el programa (o cygwin) dentro de su código, usando ProcessStartInfo.RedirectStandardInput
(y salida / error) para controlar el flujo de datos?
Tuve un problema similar hace algún tiempo, cygwin debería escribir información útil (función exacta de cygwin, texto de error y código de error WINAPI) al flujo de error, debe redirigirlo a algún lado y leer lo que escribe.