web-dev-qa-db-fra.com

Runtime.exec (). WaitFor () n'attend pas que le processus soit terminé

J'ai ce code:

File file = new File(path + "\\RunFromCode.bat");
file.createNewFile();

PrintWriter writer = new PrintWriter(file, "UTF-8");
for (int i = 0; i <= MAX; i++) {
    writer.println("@cd " + i);
    writer.println(NATIVE SYSTEM COMMANDS);
    // more things
}

writer.close();

Process p = Runtime.getRuntime().exec("cmd /c start " + path + "\\RunFromCode.bat");
p.waitFor();

file.delete();

Ce qui se passe, c'est que le fichier a été supprimé avant d'être réellement exécuté.

Est-ce parce que le .bat le fichier contient uniquement un appel système natif? Comment puis-je faire la suppression après l'exécution du .bat fichier? (Je ne sais pas quelle est la sortie du .bat le sera, car il change dynamiquement).

29
Maroun

En utilisant start, vous demandez à cmd.exe De démarrer le fichier batch en arrière-plan:

Process p = Runtime.getRuntime().exec("cmd /c start " + path + "\\RunFromCode.bat");

Ainsi, le processus que vous lancez à partir de Java (cmd.exe) Revient avant la fin du processus d'arrière-plan.

Supprimez la commande start pour exécuter le fichier de commandes au premier plan - puis, waitFor() attendra la fin du fichier de commandes:

Process p = Runtime.getRuntime().exec("cmd /c " + path + "\\RunFromCode.bat");

Selon OP, il est important d'avoir la fenêtre de console disponible - cela peut être fait en ajoutant le paramètre /wait, Comme suggéré par @Noofiz. Le SSCCE suivant a travaillé pour moi:

public class Command {

public static void main(String[] args) throws Java.io.IOException, InterruptedException {
       String path = "C:\\Users\\andreas";

       Process p = Runtime.getRuntime().exec("cmd /c start /wait " + path + "\\RunFromCode.bat");

       System.out.println("Waiting for batch file ...");
       p.waitFor();
       System.out.println("Batch file done.");
   }
}

Si RunFromCode.bat Exécute la commande EXIT, la fenêtre de commande se ferme automatiquement. Sinon, la fenêtre de commande reste ouverte jusqu'à ce que vous la quittiez explicitement avec EXIT - le processus Java attend que la fenêtre soit fermée dans les deux cas.

47
Andreas Fester

Essayez d'ajouter /wait paramètre devant la commande start.

5
Mikhail
waitForProcessOutput()

A fait l'affaire pour nous.

Voir:

http://docs.groovy-lang.org/docs/groovy-1.7.2/html/groovy-jdk/Java/lang/Process.html#waitForProcessOutput ()

Exemple de code (utilisé dans SOAPUI)

def process = "Java -jar ext\\selenese-runner.jar".execute()

process.waitForProcessOutput()

def exitValue = process.exitValue()
3
Michel

Aucun des codes décrits dans le commentaire comme réponse n'est une solution.

Première réponse

Process p = Runtime.getRuntime().exec("cmd /c start " + path + "\\RunFromCode.bat");

Deuxième réponse

Process p = Runtime.getRuntime().exec("cmd /c " + path + "\\RunFromCode.bat");

Troisième réponse

public class Command {

public static void main(String[] args) throws Java.io.IOException, InterruptedException {
       String path = "C:\\Users\\andreas";

       Process p = Runtime.getRuntime().exec("cmd /c start /wait " + path + "\\RunFromCode.bat");

       System.out.println("Waiting for batch file ...");
       p.waitFor();
       System.out.println("Batch file done.");
   }
}