# Konsolenein- und ausgabe mit ProcessBuilder



## DarkCherub (20. April 2012)

Hallo Zusammen,

ich habe eine Frage zu der Ein- und Ausgabe auf einer Konsole unter Windows, welche man mittels ProcessBuilder gestartet hat. Ich muss mehrere SCA Services starten, hierfür gibt es .bat Startscripte. Da dies einzeln immer zu umständlich war, habe ich mit ProcessBuilder herumexperimentiert und bekomme nun die einzelnen Services gestartet und erhalte auch für jeden eine Konsole. Der Code sieht ungefähr so aus:

```
String projectPath = config.getString( projectKey + ".Path" );
String batFile = config.getString( projectKey + ".Bat" );
String pathToProject = startPath + File.separator + projectPath;
Process p = new ProcessBuilder( "cmd", "/c", "start",  "\"" + projectKey + "\"", "/D", pathToProject, batFile ).start();
```

Soweit so gut, in der config sind mehrere Services definiert und für jeden wird eine Konsole gestartet in welcher der Service auf einen Tastendruck wartet und dann terminiert wird. Meine Frage ist nun, kann ich irgendwie diesen Tastendruck von dem aufrufenden Javaprogramm aus simulieren? Ich kann mir einen OutputStream besorgen:

```
OutputStream os = p.getOutputStream();
PrintWriter writer = new PrintWriter( new BufferedWriter( new OutputStreamWriter(os) ) );
writer.write( '\n' );
writer.close();
```
aber sofern ich das richtig verstehe schreibt dieser in die "falsche" Konsole, nämlich in jene, welche "start" aufgerufen hat und nicht in die, in welcher die .bat Datei ausgeführt wurde.

Gibt es hier eine einfache Möglichkeit in die "richtige" Konsole zu schreiben? 
Alternativ könnte ich das Ganze insgesamt etwas umbauen und mittels JMX (oder anderen Mitteln) eine Kommunikation zwischen dem Aufrufer und den Services implementieren, das wäre nur eben ein etwas größerer Eingriff. Ich bin auch für sontige Vorschläge offen, ich müsste nur irgendwie die gestarteten Prozesse terminieren können.

Danke im Vorraus.


----------



## deepthroat (20. April 2012)

Hi.

Du rufst da 3 Programme auf: erst cmd, welches dann start aufruft, welches dann die Batchdatei aufruft (also nochmal cmd). Warum? Nur weil du den Titel setzen willst?

Ruf doch einfach die bat Datei auf, dann solltest du auch die richtige Verbindung zur Eingabe haben.

Gruß


----------



## Thomas Darimont (20. April 2012)

Hallo,

versuchs mal so:

```
package de.tutorials.training;

import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

public class ProcessOutputExample {
    public static void main(String[] args) throws Exception{
	Process process = new ProcessBuilder("cmd","/c", "c:/temp/script.cmd")
				.redirectErrorStream(true)
				.redirectOutput(ProcessBuilder.Redirect.INHERIT) //Process out auf stdout zum testen
				.start();
	PrintWriter processOut = new PrintWriter(process.getOutputStream());
	TimeUnit.SECONDS.sleep(1);
	processOut.println();
	TimeUnit.SECONDS.sleep(1);
	processOut.println();
    }
}
```

script.cmd:

```
@echo off
echo Schritt 1
pause
echo Schritt 2
pause
echo Scrhitt 3
```

Ausgabe:

```
Schritt 1
Dr?cken Sie eine beliebige Taste . . . 
Schritt 2
Dr?cken Sie eine beliebige Taste . . . 
Scrhitt 3
```

Gruß Tom


----------



## DarkCherub (23. April 2012)

Hallo Thomas, 

danke für die Antwort. So wie du es geschrieben hast funktioniert es, wenn ich es allerdings wie folgt abändere funktioniert es nicht:


```
package de.tutorials.training;
 
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;
 
public class ProcessOutputExample {
    public static void main(String[] args) throws Exception{
    Process process = new ProcessBuilder("cmd","/c", "start", "c:/temp/script.cmd")
                .redirectErrorStream(true)
                .redirectOutput(ProcessBuilder.Redirect.INHERIT) //Process out auf stdout zum testen
                .start();
    PrintWriter processOut = new PrintWriter(process.getOutputStream());
    TimeUnit.SECONDS.sleep(1);
    processOut.println();
    TimeUnit.SECONDS.sleep(1);
    processOut.println();
    }
}
```

Der Unterschied liegt lediglich darin, dass ich mittels "start" ein neues Konsolenfenster öffne. Ich vermute einfach, dass hier die Weiterleitung nicht möglich ist, da die neue Konsole auch ein eigener Prozess ist.


----------

