# CMD aufrufen und aktuellen pfad ändern



## sandaime (25. Jul 2016)

Hallo,
ich schreibe ein Programm, was gleichzeitig meine Bachelorarbeit wird. Für das konsolengesteurte Programm Austal2000 erstelle ich eine GUI. Nun habe ich die GUI nahezu fertig und muss lediglich noch das Programm starten. Für den Start muss ich CMD aufrufen dort den Pfad in den Ordner setzen wo austal.exe ist und anschließen eine Eingabe tätigen. Die Eingabe sieht wie folgt aus C:\a2k\austal2000 "Projektname" und danach startet das Programm. Nun zu meinem Problem. Die Pfade habe ich abgesichert und kann auf die zugreifen jedoch kann ich diese nicht an CMD übergeben. Ich starte CMD mit Runtime.getRuntime(), aber wie nehme ich im CMD eingaben vor?

```
try {
                Process p = Runtime.getRuntime().exec("cmd /C start");
       
                //will diese gespliteten Pfad als erstes eingeben, damit sich der Pfad von CMD
                //ändert
                String[] geteilterPfad = austalPfad.split("austal2000.exe",2);
                //Dies ist nur zum prüfen ob der split geklappt hat
                System.out.println(geteilterPfad[0]+ " Eingabe für das ändern des pfades");
                //Wenn der pfad geändert ist will ich den Projektnamen übergeben und "austal2000"
                //schreiben lassen und diese eingebe bestätigen
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
```


Für jede Hilfe wäre ich sehr dankbar ich bin kurz vor dem Ende und das ist wichtig wegen meiner Bachelorarbeit  danke an diese super community


----------



## JCODA (25. Jul 2016)

Du könntest die Konsole statt mit "cmd /C start" mit wiefolgt starten: 

```
Process p = Runtime.getRuntime().exec("cmd /K \"cd /d c:\\Programme\\ \"");
```

Ich bin mir aber nicht sicher, ob das das ist, was du möchtest. 
ggf. kannst du auch im nachhinein mit cd Pfad 
deinen Pfad ändern. 

Warum überhaupt per CMD-Konsole und nicht direkt das Programm per Java starten?


----------



## sandaime (25. Jul 2016)

Kannst bitte mehr erzählen. Also wie das funktionieren würde und was deine Idee ist?


----------



## JCODA (25. Jul 2016)

Hilft dir vielleicht folgendes? 

```
import java.io.IOException;
import java.io.OutputStream;


public class Blub {

    public static void main(String[] args) throws IOException, InterruptedException {
         Process p = Runtime.getRuntime().exec("cmd"); //Ohne sichtbares Fenster
         OutputStream out = p.getOutputStream();
         out.write("cd D:\n".getBytes());//Ordner wechseln
         out.flush();
         out.write("dir\n".getBytes());//Befehl ausführen
         out.flush();
        
         while(true){//Auf Antwort warten...
             Thread.sleep(1000);
             byte buff [] = new byte[1000];
            
             if(p.getInputStream().read(buff) > 0){
                 System.out.println(new String(buff));
             }
            
         }
        
    }

}
```

Ich kenne mich damit nicht wirklich aus, ist nur so dahingetippt.


----------



## sandaime (25. Jul 2016)

Jeder Tipp ist ein Weg zum Ziel  danke ich werde mich mal bisschen in TryError versuchen  Halte dich auf dem laufenden und für andere Tipps bin ich weiterhin offen


----------



## Meniskusschaden (26. Jul 2016)

Ich würde mir auch mal die Klasse ProcessBuilder ansehen. Das scheint gegenüber `Runtime.getRuntime().exec()`die modernere Variante zu sein, um externe Programme zu starten. Da gibt es auch eine Methode, um das Arbeitsverzeichnis zu setzen. Vielleicht geht es damit komfortabler.


----------



## sandaime (30. Jul 2016)

Hallo,
ich habe die Lösung gefunden. Mit einem Processbuilder habe ich es gelöst. Zurzeit gebe ich es nur inder Java Konsole aus, aber als nächstes werde ich es in einer TextArea ausgeben, damit alles sichtbar für den User ist.


```
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", "cd \"C:\\a2k\" && austal2000 testprojekt");
        builder.redirectErrorStream(true);
        Process p = null;
        try {
            p = builder.start();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = null;
        while (true) {
            try {
                line = r.readLine();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if (line == null) {
                break;
            }
            System.out.println(line);
        }
```


----------



## mrBrown (30. Jul 2016)

Du kannst auch einfach mit #directory das Arbeitsverzeichnis setzte, ist imho der elegantere Weg.
Außerdem kannst du dir den Weg über cmd dann sparen (oder muss das bei Windows so?), und dein Programm direkt starten.

Dein ExceptionHandling ist auch etwas suboptimal...
Wirft `builder.start()`, fängst du die zwar, bekommst aber direkt danach eine NPE, weil `p` nie initialisiert wurde


----------



## sandaime (30. Jul 2016)

Das ist die Version, was ich als Grundlage habe. Ich muss diese noch weiter anpassen. 
Das Programm wird in der Konsole gestartet und dort sieht man in prozent wie weit die Rechnung ist. 

#direcetory kann ich leider nicht direkt setzen, weil der User den Ordner überall hinstellen könnte worin die austal2000.exe ist, aber das Fange ich mit einer Configdatei ab, worin der Pfad drinnen ist. Also muss ich erst in die Directory wechseln worin die "Austal2000.exe" ist. In diesem Pfad befindet sich dann das Projektordner vom User. Im zweiten Schritt muss folgender Befehl rein "Austal2000 "projektname"" --> Programm startet.

Ich hoffe ich konnte halbwegs erzählen, welche schritte erstellt müssen. 

Falls Ihr Ideen habt immer gerne. Ich lehne keine Idee ab  danke nochmals an alle die kommentiert haben


----------



## Meniskusschaden (30. Jul 2016)

mrBrown hat gesagt.:


> Außerdem kannst du dir den Weg über cmd dann sparen (oder muss das bei Windows so?), und dein Programm direkt starten.


Ich glaube, das ist nur bei internen Befehlen erforderlich, also bei den Befehlen, die nicht als ausführbare Datei vorliegen, sondern Bestandteil von cmd.exe sind. In diesem Fall müsste es also wirklich ohne cmd gehen.


----------



## mrBrown (30. Jul 2016)

sandaime hat gesagt.:


> #direcetory kann ich leider nicht direkt setzen, weil der User den Ordner überall hinstellen könnte worin die austal2000.exe ist, aber das Fange ich mit einer Configdatei ab, worin der Pfad drinnen ist. Also muss ich erst in die Directory wechseln worin die "Austal2000.exe" ist. In diesem Pfad befindet sich dann das Projektordner vom User. Im zweiten Schritt muss folgender Befehl rein "Austal2000 "projektname"" --> Programm startet.



Und was sollte das ändern? 
Der #directory-Aufruf käme *nach* new ProcessBuilder, also an einer Stelle, wo du den Pfad schon kennen musst.
Wenn du's mit #directory machst, kannst du dir dann CMD sparen und cd sparen, und dein command reduziert sich auf den wirklichen Start deiner exe, und der Rest kann wegfallen -> es wird übersichtlicher und leserlicher


----------



## sandaime (30. Jul 2016)

Danke für diesen Tipp es erspart mir grade einiges (Y)


----------

