Process - Ausgabe leer

schlingel

Gesperrter Benutzer
Hallo Leute, ich hab folgendes Problem: Ich möchte per WMI Infos vom PC auslesen. Da es sich bei der App um eine Webstart-App handelt, möchte ich weder DLLs noch sonst irgendwelche zusätzlichen JARs ausliefern.

Meine erste Idee war also die WMIC per Process auszuführen und die Ausgabe zu parsen.

So kann ich z.B. wenn ich lokal am PC sitze per "wmic memphysical" einiges über den vorhandenen Speicher in Erfahrung bringen.

Doch wenn ich das ganze per Java-Process ausführe, bekomme ich keine Ausgabe. Der Prozess cheint stehen zu bleiben. Mein erster Verdacht: Das Ding startet im CLI Modus. Nagut, Workaround ist schnell gefunden: Ich verwende eine Bat-Datei und starte über die das ganze.

Doch das Resultat bleibt das gleiche. Die Ausgabe bleibt leer.

Zu Testzwecken hab ich dann folgende Bat-Datei geschrieben:
Code:
wmic memphysical > ./temp.txt

Führe ich das File aus funktioniert es.

Führe ich das Script per Java aus, funktioniert es nicht. Mit folgendem Code tue ich das:
Code:
               File tmpFile = File.createTempFile("tmp2", ".txt");
		tmpFile.deleteOnExit();
		System.out.println("Pfad: " + tmpFile.getParent());
		File exec = new File(tmpFile.getParent(), "test.bat");
		List<String> execs = new ArrayList<String>();
		execs.add(exec.getAbsolutePath());
		System.out.println(exec.getAbsolutePath());
		
		ProcessBuilder pb = new ProcessBuilder(execs);
		pb.directory(tmpFile.getParentFile());
		Process p = pb.start();
		Scanner s = new Scanner(p.getInputStream());
		
		if(s.hasNextLine()) {
			System.out.println(s.nextLine());
			p.destroy();
		}
		
		s.close();
		System.out.println("Ergebnis: " + p.waitFor());

Das File liegt im Temp-Verzeichnis. Es existiert und wenn ich es mit Doppelclick starte, tut es was es soll. Starte ich es per Java wird das temp.txt angelegt, bleibt aber leer. Der Prozess hat irgendwelche Probleme denn er returniert immer 1.

Ich weiß aber nicht woran es liegt. Irgendwelche Ideen?
 
Hm, wo genau meinst du dass es hingehört? Nach dem Scannen der Ausgabe habe ich es ja eh in der Zeile:
Code:
System.out.println("Ergebnis: " + p.waitFor());

Und vorher hat das glaub ich keinen Sinn.
 
Der startende Thread sollte auf das Ende des Prozesses warten, das Auslesen von STDOUT sollte in einem eigenen Thread laufen. STDERR nicht vergessen, da kann auch was kommen.
 
Hallo - ja genau das ist es dann gewesen.

Code:
	stdOutReader = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("Starting reading");
				if(wmicProc == null)
					return;
				
				wmicOutput = "";
				Scanner s = new Scanner(wmicProc.getInputStream());
				String curLine = "";
				
				while(s.hasNextLine()) {
					curLine = s.nextLine();
					wmicOutput += curLine;
					
					System.out.println(curLine);
				}
			}
		});
		
		stdErrReader = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("Starting reading");
				
				if(wmicProc == null)
					return;
				
				wmicErrOutput = "";
				Scanner s = new Scanner(wmicProc.getErrorStream());
				String curLine = "";
				
				while(s.hasNextLine()) {
					curLine = s.nextLine();
					wmicErrOutput += curLine;
					
					System.out.println("Error: " + curLine);
				}				
			}
		});

Damit initialisiere ich die zwei Reader-Thread. So starte ich dann den Thread:

Code:
		List<String> execs = new ArrayList<String>();
		execs.add(WMIC_COMMAND);
		execs.add(WMIC_PHYSICAL_MEMORY);
		System.out.println(WMIC_PHYSICAL_MEMORY);
		
		//String exec = String.format("%s %s", getWmicPath(), WMIC_PHYSICAL_MEMORY);

		ProcessBuilder pb = new ProcessBuilder(execs);
		pb.directory(tmpFile.getParentFile());
		wmicProc = pb.start();
		
		stdOutReader.start();
		stdErrReader.start();
		
	
		BufferedWriter w = new BufferedWriter(new PrintWriter(wmicProc.getOutputStream()));
		w.close(); 
		
		System.out.println("Ergebnis: " + wmicProc.waitFor());

		stdOutReader.interrupt();
		stdErrReader.interrupt();

Des Problems Lösung war wohl das:
Code:
		BufferedWriter w = new BufferedWriter(new PrintWriter(wmicProc.getOutputStream()));
		w.close();

Ohne diese zwei zeilen funktioniert es nicht. Den stderr-Reader kann ich aber z.B. wegnehmen. Wenn da wer Hintergrundinformationen hat wäre ich sehr interessiert 🙂
 
Danke für diese Info! :toll:

Ich bin letzte Woche auf die gleiche Problematik gestossen
und habe mich dann im Endeffekt über JNI gerettet. :autsch:
 

Neue Themen


Zurück
Oben