ProcessBuilder - Prozess wird nicht beendet

Ashaman

Mitglied
Hallo,

ich stehe leider wie der Ochs vorm Berg...
Situation:
Ich möchte über den ProcessBuilder die psexec der pstools aufrufen um damit eine Datei über das Netzwerk auszuführen.
Wenn der Prozess nach einer bestimmten Zeit kein Ergebnis liefert soll er zerstört werden.

Problem:
Der ProcessBuilder startet wie gewünscht die "psexec".
Zum Test hab ich die Streams umgeleitet und bemerkt, dass der Aufruf generell länger braucht als wenn ich es über die Kommandozeile aufrufe. Warum?
Jetzt das eigentliche Problem. Wird die Methode destroy() aufgerufen tut sich nix, wenn die Streams umgeleitet sind. "waitFor()" wird nicht abgebrochen.
Sind die Streams nicht umgeleitet bricht "waitFor" zwar ab aber ich sehe die psexec immer noch im Task Manager. Sie wird also nicht beendet. Wie kann ich das umsetzen?

Da dieser Vorgang sehr oft abläuft würde ich ansonsten sehr viele psexec laufen haben die sich erst nach langer Zeit verabschieden.

Code (Der Timer läuft in einem anderen teil und führt nur process.destroy() aus):
Code:
import java.io.File;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;


public class Problem {

    private final boolean DEBUG = true;
    private String ip;
    private String datei;
    private Process process;

    public Problem(String ip, String datei) {
        this.ip = ip;
        this.datei = datei;
    }
    
    public boolean test() {
        boolean result = false;
        try {
             File f = new File("./pstools/psexec.exe");
             ProcessBuilder builder = new ProcessBuilder(f.getAbsolutePath(),
                "-n", "3", "\\\\" + ip, datei);
             builder.directory(f.getParentFile());
             builder.redirectErrorStream(true); 
             process = builder.start();
            if (DEBUG) {
                BufferedReader reader = new BufferedReader(new
                            InputStreamReader(process.getInputStream()));
                String s;
                while((s = reader.readLine()) != null) {
                    System.out.println(s);
                }
            }
            process.waitFor();
            if (DEBUG) {
                System.out.println("ExitValue: " + process.exitValue());
            }
            if (process.exitValue() == 0) {
                result = true;
            }
        } catch(IOException exception) {
            exception.printStackTrace();
        } catch(InterruptedException exception) {
            exception.printStackTrace();
        }
        return result;
    }
    public static void main(String[] args) {
        boolean result = new Problem("127.0.0.1", "c:\\a.bat").test();
        System.out.println("Ergebnis der Funktion: " + result);
        
    }
}

Könnte mir jemand bitte sagen, was ich falsch mache?

P.S.::confused:
ich weiß leider nicht, wie man eine Datei auf einem Netzwerkrechner direkt per java ausführt und ob das überhaupt geht.
 
Zuletzt bearbeitet:

zeja

Erfahrenes Mitglied
Erstmal ist es unschön Code zu posten der nicht mal compiliert. Da weiß ich nicht wo ich anfangen soll... Code berichtigen kann ja nicht der Sinn und Zweck sein.

Dann brauchst du die Streams auf jeden Fall nicht zu schließen. Du musst nur Streams schließen die du selber erstellst, nicht aber die von dem Prozess, da kümmert der sich selber drum.

Und es kann gut sein dass du eine Exception bekommst, aber nie davon erfährst weil deine catch-Blöcker leer sind. Sowas niemals machen! Immer zumindest ein e.printStackTrace da rein.
 

Ashaman

Mitglied
okay.. ich bau den code mal um... das mit den streams war ja nur zum test..
Was die exceptions angeht.
Es gibt keine. Ich hab die erst geleert nachdem ich das getestet hab.
Code korrigieren? na ja es ist doch ne recht simple Funktion.
Vielleicht seh ich den Wald vor lauter Bäumen nicht?

Tipps wären schon eine große Hilfe.

EDIT:
Code angepaßt
das unglaubliche ist aber des der Code da Oben so ca 10 mal wunderbar funktioniert hat. Genau so wie es soll.
Ich hab ihn in einer extra Klasse zum Test laufen lassen.
Dann plötzlich läufts genau wie im eigentlich Programm. Ich bekomme einen Teil ausgegeben und es hängt.
Dabei habe ich absolut nichts im Code verändert. Rein gar nichts.

Das gibt mir der InpuStream und dann hängt der Prozess, wie immer bewirkt process.destroy() nichts:

PsExec v1.94 - Execute processes remotely
Copyright (C) 2001-2008 Mark Russinovich
Sysinternals - http://www.sysinternals.com
 
Zuletzt bearbeitet:

Ashaman

Mitglied
Es scheint als ob der destroy() Befehl erst ausgeführt wird nachdem der Prozess wieder reagiert, denn sobald die psexec auf den Timeout wartet hängt auch der destroy() Befehl.

Mir stellen sich folgende Fragen:

1. Ist das ein normales Verhalten?
2. Kann man das umgehen?
3. Alternativ... gibt es eine andere Möglichkeit so einfach wie möglich auf einem Remote-PC eine Datei ausführen zu lassen?
4. Was mir noch sehr wichtig wäre... Wie kann man den Prozess direkt beenden?
(Damit mein ich den Windows-Prozess psexec in diesem Fall, da von diesen viele im Task-Manager stehen bleiben)

Wäre wirklich sehr nett, wenn mir jemand helfen könnte :)
 

joschi70

Erfahrenes Mitglied
Hi Ashaman,

leider kenne ich das Prog psexec nicht.
Keine Ahnung, ob es was hilft, aber versuch mal vor dem process.waitFor(); alle Streams zu schliessen:

Code:
process.getInputStream().close();
process.getOutputStream().close();
process.getErrorStream().close();

Gruß
joschi