40

I have this 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();

What happens is that the file deleted before it actually executed.

Is this because the .bat file contains only native system call? How can I make the deletion after the execution of the .bat file? (I don't know what the output of the .bat file will be, since it dynamically changes).

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • Did it work? I have similar issue http://stackoverflow.com/questions/28917268/java-program-terminates-before-completion-of-command-in-batch-file Looking for solution.. – Nayeem Mar 08 '15 at 13:02
  • Is it work to you? I have the same problem, and even I exec the process like you, when I add '/wait' my program stuck on waiting. Do you have solution? – Rat Apr 06 '16 at 15:35

4 Answers4

54

By using start, you are askingcmd.exe to start the batch file in the background:

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

So, the process which you launch from Java (cmd.exe) returns before the background process is finished.

Remove the start command to run the batch file in the foreground - then, waitFor() will wait for the batch file completion:

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

According to OP, it is important to have the console window available - this can be done by adding the /wait parameter, as suggested by @Noofiz. The following SSCCE worked for me:

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.");
   }
}

If RunFromCode.bat executes the EXIT command, the command window is automatically closed. Otherwise, the command window remains open until you explicitly exit it with EXIT - the java process is waiting until the window is closed in either case.

Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
  • 1
    Removing `start` will hide the CMD, which I don't want to happen. Is there another way to still have the CMD opened while the execution? – Maroun Mar 04 '13 at 10:16
  • So you want to see the output from the batch file in the command window? – Andreas Fester Mar 04 '13 at 10:19
  • Yes, it is important for this task. – Maroun Mar 04 '13 at 10:19
  • 1
    What If I want to launch a third party program, like this; Process p = Runtime.getRuntime().exec("C:\\Program Files\\CCleaner\\CCleaner64.exe"); Calling process.watFor(); Returns immediatly, just like op. – Essej Jul 19 '16 at 16:37
  • 1
    @Baxtex This is specific to the application you are launching. For example, I tried the same with `Process p = Runtime.getRuntime().exec("c:\\Windows\\System32\\notepad.exe");` and it waits as expected, while I can reproduce that `CCleaner64.exe` does not wait. I assume that `CCleaner64` launches a child process so that the original process which is started with `exec()` returns immediately. – Andreas Fester Jul 20 '16 at 05:34
  • @AndreasFester I see. I have serached alot regarding this issue and just as you say, it may be due to other programs launch their own processes so that their main process might end quite fast. I'v have to try figure something out... – Essej Jul 20 '16 at 07:50
  • cmd /c start /wait - This won't execute in Linux - Please suggest us some alternatives for Ubuntu Linux. – Sudhir Belagali Jul 18 '20 at 04:34
  • p.s. the Process class also has the "wait()" method, but that's from the Object class, it's more like the thread's wait. So look out which method are you using – Songzhw Mar 12 '23 at 16:22
7

Try adding /wait parameter in front of the start command.

Petro
  • 3,484
  • 3
  • 32
  • 59
Mikhail
  • 4,175
  • 15
  • 31
5

None of the code described in the commentary mark as answer is a solution.

First Answer

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

Second Answer

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

Third Answer

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.");
   }
}
4
waitForProcessOutput()

Did the trick for us.

See:

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

Code Example (used in SOAPUI)

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

process.waitForProcessOutput()

def exitValue = process.exitValue()
Michel
  • 9,220
  • 13
  • 44
  • 59