2009-01-16 13 views
7

Das ist mein Problem. Ich habe ein Programm, das in einem TTY laufen muss, cygwin stellt dieses TTY zur Verfügung. Wenn ich stdIn umleite, schlägt das Programm fehl, weil es kein TTY hat. Ich kann dieses Programm nicht ändern und benötige eine Art, es zu automatisieren.Wie wird die Eingabe an die Konsole gesendet, als würde der Benutzer tippen?

Wie kann ich das cmd.exe Fenster greifen und es Daten senden und es denken lassen, dass der Benutzer es eintippt?

Ich benutze C#, ich glaube, es gibt einen Weg, es mit java.awt.Robot zu tun, aber ich muss C# aus anderen Gründen verwenden.

+0

siehe auch die andere Frage dazu: http: //stackoverflow.com/questions/450741/getting-the-pipe-from-rsync-to-run-asa-script –

+0

das war meine andere Frage, ich entschied mich, einen anderen Weg zu versuchen, daher eine andere Frage – Malfist

Antwort

1

Das klingt wie eine Aufgabe für SendKeys(). Es ist nicht C#, aber VBScript, aber nontheless - Sie bat um einige Weg, es zu automatisieren:

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}" 
+0

Ich sah SendKeys bereits. SendKey ist Teil des .NET 2.0-Framework, so dass ich es aus C# verwenden kann. Ich werde sehen, ob das funktioniert. – Malfist

+0

Wie kann ich das in C# arbeiten lassen? – Malfist

+1

Die Verwendung der SendKeys-Klasse erfordert grundsätzlich, dass Sie das TTY aktiv machen - dann rufen Sie einfach SendKeys.Send auf und es sendet die Tastenanschläge. –

1

Können Sie das Programm (oder Cygwin) innerhalb Ihres Codes starten, indem Sie ProcessStartInfo.RedirectStandardInput (und Ausgabe/Fehler) verwenden, um den Datenfluss zu steuern?

+0

I kann damit anfangen. Aber sobald es der Punkt ist, an dem das Programm den TTY haben muss, scheitert es. Das Programm fragt nach einem Passwort und ändert das TTY, um die Tastenanschläge zu verbergen. Dies kann nicht mit einem umgeleiteten Stream geschehen, so dass es fehlschlägt. – Malfist

+0

Hast du ein gutes Beispiel für diesen Jon? –

+0

@ Longhorn213: Nicht ohne eine Menge Arbeit, nein :( –

0

ich vor einiger Zeit ähnliches Problem hatte, Cygwin einige nützliche Informationen (genaue Cygwin Funktion, Fehler schreiben sollte Text und WINAPI-Fehlercode) in den Fehler-Stream, Sie sollten es irgendwo umleiten und lesen, was es schreibt.

+0

Nein, Cygwin schreibt _everything_ in den StandardErrorStream.Der Fehler ist über das ioclt unpassend für das Gerät, das bedeutet, ich brauche ein echtes TTY, damit es benutzt werden kann. – Malfist

+0

Können Sie hier eine vollständige Fehlermeldung von cygwin einfügen? – okutane

+0

bash: [####: #] tcsetattr: Ungültige ioctl für Gerät – Malfist

5

Ich habe herausgefunden, wie Sie die Eingabe an die Konsole senden. Ich habe das verwendet, was Jon Skeet gesagt hat. Ich bin nicht 100% sicher, dass dies der richtige Weg ist, dies zu implementieren.

Wenn es Kommentare gibt, um dies besser zu machen, würde ich gerne hier. Ich tat das nur, um zu sehen, ob ich es herausfinden könnte. Hier

ist das Programm, das ich sah, dass für Eingabeformular der Benutzer gewartet

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); 
    } 
} 

Dies ist die Konsole app Schreiben an den anderen

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); 
    } 
}