Come inviare input alla console come se l'utente stesse scrivendo?
-
19-08-2019 - |
Domanda
Questo è il mio problema. Ho un programma che deve essere eseguito in un TTY, cygwin fornisce questo TTY. Quando reindirizzo stdIn il programma fallisce perché non ha un TTY. Non posso modificare questo programma e ho bisogno di un modo per automatizzarlo.
Come posso catturare la finestra di cmd.exe e inviarlo dati e fargli credere che l'utente lo stia digitando?
Sto usando C #, credo che ci sia un modo per farlo con java.awt.Robot ma devo usare C # per altri motivi.
Soluzione
Sembra un compito per SendKeys ()
. Non è C #, ma VBScript, ma comunque - hai chiesto qualche modo di automatizzarlo:
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}"
Altri suggerimenti
Ho capito come inviare l'input alla console. Ho usato quello che ha detto Jon Skeet. Non sono sicuro al 100% che questo sia il modo corretto di implementarlo.
Se ci sono commenti per migliorare questo mi piacerebbe qui. L'ho fatto solo per vedere se riuscivo a capirlo.
Ecco il programma che ho fissato in attesa di input dall'utente
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);
}
}
Questa è l'app console che scrive sull'altra
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);
}
}
Puoi avviare il programma (o cygwin) nel tuo codice, usando ProcessStartInfo.RedirectStandardInput
(e output / errore) per controllare il flusso di dati?
Ho avuto un problema simile qualche tempo fa, cygwin dovrebbe scrivere alcune informazioni utili (esatta funzione cygwin, testo di errore e codice di errore WINAPI) sul flusso di errori, dovresti reindirizzarlo da qualche parte e leggere ciò che scrive.