Hallo, statt vieler Fragen, hier gleich mal vorneweg eine Lösung für ein Problem, das mich seit einigen Tagen zu einer intensiven Recherche gezwungen hat; alleine, selbst dieses tolle Forum hier hat mir nicht direkt die Lösung geliefert, aber doch wichtige Hinweise geliefert. Daher möchte ich (quasi als 'Einstand') auch mal ein bereits gelöstes Problem hier veröffentlichen.
Die Aufgaben war, aus einem laufenden Java-Programm ein DOS-Fenster mit einer Befehlszeile zu öffnen. Hört sich einfach an, ist auch schon verschiedentlich veröffentlicht worden, trifft aber nicht genau meine Bedürfnisse. Ich wollte, dass nach Ausführung der Befehlszeile (die im Speziellen im Java-Prog zusamengebaut wird) das Dos-Fenster mit dem Ergebnis (als der Output des jew. Programmes) stehen bleibt, um vom Menschen gelesen werden zu können.
Dass im Speziellen die Befehlszeile selbst ein Aufruf java "Pfade" "MAIN-Classe" "Parameter" darstellt ist dabei zwar unerheblich, aber eben der für mich interessante Teil (ich habe eine JAVA-MAIN Klasse, die ich als 'unabhängiges' Programm in einem DOS Fenster öffnen muss, aber eben aus einem anderen Java Programm heraus, z.B einer mit GUI, also Swing z.B.)
Die Lösung:
die viel bekannte Befehlszeile (genauer: das Argument von exec) rund um Runtime.getRuntime().exec() muss nur einen speziellen Aufbau haben, auf den mich leider bisher keine Recherche gebracht hat, sondern stures Ausprobieren. Man schreibt wie folgt:
Lösung:
Process p = Runtime.getRuntime.exec("cmd /k start cmd /k java -classpath C:\\Users\\<ich>\\...\\bin;C:\\Users\\...z.B Pfad zu externen Libraries\\blabla.jar package.class-die-main-enthält <parameter>")
wobei die <parameter> die in Java auslesbaren CMD-Line-Parameter sind, oder, wie ich es mache: mit einer Library JSAP, damit kann man UNIX-Style Kommandozeilenbefehe mit Parametern angeben.
Der 'Trick', wenn man so will, besteht in dem 2malig hintereinander aufgeführten 'cmd /k'. Warum das so ist, vermag ich nicht genau zu erklären, es muss speziell an Windows liegen (Vielleicht sollte man vorab dazu sagen: es geht hier um die Windows/DOS Welt).
Als Vergleich (und um meine Annäherung an die Lösung nachzuvollziehen) möge man ein DOS (cmd) Fenster öffnen und verschiedenen Eingabe-Zeilen ausprobieren (so habe ich mich an die Lösung herangetastet):
1) "cmd /k start" öffnet ein neues DOS-Fenster, das auch nicht sofort wieder verschwindet
2) "start" öffnet ein neues DOS Fenster
3) "start java -version" öffnet ein neues DOS-Fenser, führt den Befehl aus, blitzschnell verschwindet das DOS Fenster aber wieder.
Den Befehl "start /k" gibt es aber nicht
4) Der Befehl "cmd start java -version" öffnet innerhalb des bestehenden DOS-Fensters eine neue Interpreter-Ebene und führt dort den Befehl "java -version" aus, schön, aber das ist leider keine >neues< DOS-Fenster. (bitte hier 'exit' eingeben, damit schliesst man nicht das Fenster, man kommt auf die vorige Ebene des DOS-Kommandozeileninterpreters zurück, und kann wieder mit Pfeil-UP und DOWN durch die alten Befehle scrollen).
Bisher also alles noch nicht das, was ich wollte. Also weiter:
5) "start cmd/k java -version" hat unverhoft Erfolg: es wird ein DOS-Fenster geöffnet, ein Befehl ausgeführt und das DOS Fenster bleibt offen
Geben wir die Zeile 5) als Argument in Runtime.getRuntime().exec(<Zeile 5>) ein, und führen das als kleines Java-Programm aus (z.B wie ich in Eclipe, mit Shift-F11), so passiert - ups: ein Fehler in der Console (cannot run Programm start......).
6) die Zeile cmd start cmd/k java -version als exec-Argument: wird ohne Fehler ausgeführt, aber: kein DOS-Fenster erscheint (warum auch immer, vllt ist es so schnell wieder weg, dass man es erst gar nicht sieht, ?); auch ein fehlerhaftes 'java -vers' Kommando (als Argument für das exec) gibt bei Ausführung in Eclipse kein wie auch immer geartetes DOS-Fenster mit vielleicht einer Fehlermeldung von java
7) die Zeile cmd /k start cmd java -version im Eclipse-Testprogramm öffnet zwar ein DOS-Fenster, das auch stehen bleibt und nicht blitzartig wieder geschlossen wird; aber der Befehl zur Java-Version wird schlicht ignoriert (seltsam, aber wahr)
8) Tatsächlich erst das Argument cmd /k start cmd /k java -version ist die oben erwähnte Lösung als exec-Argument.
Nachtrag, 9). das Argument cmd /k start \"titel\" cmd /k java -version für Runtime.exec() öffnet ein DOS-Fenster mit einem Titel in der Window-Titelleiste.
(PS: DOS/Windows Dateipfade als String -Argument in Java-Quelltext müssen mit einem Doppel-Backslash maskiert werden)
Ich hoffe, damit einigen Suchenden ein paar wertvolle Hinweise gegeben zu haben.
Die Aufgaben war, aus einem laufenden Java-Programm ein DOS-Fenster mit einer Befehlszeile zu öffnen. Hört sich einfach an, ist auch schon verschiedentlich veröffentlicht worden, trifft aber nicht genau meine Bedürfnisse. Ich wollte, dass nach Ausführung der Befehlszeile (die im Speziellen im Java-Prog zusamengebaut wird) das Dos-Fenster mit dem Ergebnis (als der Output des jew. Programmes) stehen bleibt, um vom Menschen gelesen werden zu können.
Dass im Speziellen die Befehlszeile selbst ein Aufruf java "Pfade" "MAIN-Classe" "Parameter" darstellt ist dabei zwar unerheblich, aber eben der für mich interessante Teil (ich habe eine JAVA-MAIN Klasse, die ich als 'unabhängiges' Programm in einem DOS Fenster öffnen muss, aber eben aus einem anderen Java Programm heraus, z.B einer mit GUI, also Swing z.B.)
Die Lösung:
die viel bekannte Befehlszeile (genauer: das Argument von exec) rund um Runtime.getRuntime().exec() muss nur einen speziellen Aufbau haben, auf den mich leider bisher keine Recherche gebracht hat, sondern stures Ausprobieren. Man schreibt wie folgt:
Lösung:
Process p = Runtime.getRuntime.exec("cmd /k start cmd /k java -classpath C:\\Users\\<ich>\\...\\bin;C:\\Users\\...z.B Pfad zu externen Libraries\\blabla.jar package.class-die-main-enthält <parameter>")
wobei die <parameter> die in Java auslesbaren CMD-Line-Parameter sind, oder, wie ich es mache: mit einer Library JSAP, damit kann man UNIX-Style Kommandozeilenbefehe mit Parametern angeben.
Der 'Trick', wenn man so will, besteht in dem 2malig hintereinander aufgeführten 'cmd /k'. Warum das so ist, vermag ich nicht genau zu erklären, es muss speziell an Windows liegen (Vielleicht sollte man vorab dazu sagen: es geht hier um die Windows/DOS Welt).
Als Vergleich (und um meine Annäherung an die Lösung nachzuvollziehen) möge man ein DOS (cmd) Fenster öffnen und verschiedenen Eingabe-Zeilen ausprobieren (so habe ich mich an die Lösung herangetastet):
1) "cmd /k start" öffnet ein neues DOS-Fenster, das auch nicht sofort wieder verschwindet
2) "start" öffnet ein neues DOS Fenster
3) "start java -version" öffnet ein neues DOS-Fenser, führt den Befehl aus, blitzschnell verschwindet das DOS Fenster aber wieder.
Den Befehl "start /k" gibt es aber nicht
4) Der Befehl "cmd start java -version" öffnet innerhalb des bestehenden DOS-Fensters eine neue Interpreter-Ebene und führt dort den Befehl "java -version" aus, schön, aber das ist leider keine >neues< DOS-Fenster. (bitte hier 'exit' eingeben, damit schliesst man nicht das Fenster, man kommt auf die vorige Ebene des DOS-Kommandozeileninterpreters zurück, und kann wieder mit Pfeil-UP und DOWN durch die alten Befehle scrollen).
Bisher also alles noch nicht das, was ich wollte. Also weiter:
5) "start cmd/k java -version" hat unverhoft Erfolg: es wird ein DOS-Fenster geöffnet, ein Befehl ausgeführt und das DOS Fenster bleibt offen
Geben wir die Zeile 5) als Argument in Runtime.getRuntime().exec(<Zeile 5>) ein, und führen das als kleines Java-Programm aus (z.B wie ich in Eclipe, mit Shift-F11), so passiert - ups: ein Fehler in der Console (cannot run Programm start......).
6) die Zeile cmd start cmd/k java -version als exec-Argument: wird ohne Fehler ausgeführt, aber: kein DOS-Fenster erscheint (warum auch immer, vllt ist es so schnell wieder weg, dass man es erst gar nicht sieht, ?); auch ein fehlerhaftes 'java -vers' Kommando (als Argument für das exec) gibt bei Ausführung in Eclipse kein wie auch immer geartetes DOS-Fenster mit vielleicht einer Fehlermeldung von java
7) die Zeile cmd /k start cmd java -version im Eclipse-Testprogramm öffnet zwar ein DOS-Fenster, das auch stehen bleibt und nicht blitzartig wieder geschlossen wird; aber der Befehl zur Java-Version wird schlicht ignoriert (seltsam, aber wahr)
8) Tatsächlich erst das Argument cmd /k start cmd /k java -version ist die oben erwähnte Lösung als exec-Argument.
Nachtrag, 9). das Argument cmd /k start \"titel\" cmd /k java -version für Runtime.exec() öffnet ein DOS-Fenster mit einem Titel in der Window-Titelleiste.
(PS: DOS/Windows Dateipfade als String -Argument in Java-Quelltext müssen mit einem Doppel-Backslash maskiert werden)
Ich hoffe, damit einigen Suchenden ein paar wertvolle Hinweise gegeben zu haben.
Zuletzt bearbeitet: