简体   繁体   中英

ProcessBuilder doesn't lauch batch files if application terminates too fast - other tasks are launched correctly

I am trying to launch a batch file right after my application terminates (auto-update file which will replace old jar with new jar). I decided for this pattern:

new ProcessBuilder("cmd", "/C "+batch_file.getAbsolutePath()+"").start();

Originally I was trying just this:

new ProcessBuilder(batch_file.getAbsolutePath()).start();

I was hoping use of cmd instead of calling file name directly would increase reliability. But both options fail if my program terminates instantly after that. U have to use sleep:

  public static void main(String[] args) throws Exception {
    File batch = new File("test_update.bat");
    // It doesn't work without this
    Thread.sleep(1000);
    new ProcessBuilder(batch.getAbsolutePath()).start();
  }

Without sleep, I don't see anything happening at all. However the weirdest thing is that other commands do not suffer from this issue:

// Will run two instanced of notepad synchronously one after another
new ProcessBuilder(new String[] {"cmd", "/C notepad&&notepad"}).start();

I tried to combine it:

new ProcessBuilder("cmd", "/C notepad \""+batch.getAbsolutePath()+"\"&&"+batch.getAbsolutePath()+"&&notepad").start();

This sequence is supposed to open my batch file in notepad (so I can see it exists and isn't malformed), run the batch file and then notepad again. Only first notepad launches, then the cmd instance disappears from the task manager.

Can anyone confirm this strange behavior? And more importantly: can you explain it to me and propose a solution?

Sleeping for 1 second after calling ProcessBuilder is not an ideal solution!

This is really a nasty thing. Apparently, Windows does keep track of the output stream for the batch files and closes cmd.exe if the stream is closed/unused before starting next command. The workaround I used was to redirect the output stream to a file (it's better to log batch output anyway):

ProcessBuilder pb = new ProcessBuilder("cmd", "/K "+batch.getAbsolutePath()+">batchlog.txt");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM