19

In my Java program, I create a process that executes a command to run a batch file like this:

try {
        File tempFile = new File("C:/Users/Public/temp.cmd");
        tempFile.createNewFile();
        tempFile.deleteOnExit();


        setContents(tempFile, recipe.getText()); //Writes some user input to file
        String cmd = "cmd /c start " + tempFile.getPath();


        Process p = Runtime.getRuntime().exec(cmd);


        int exitVal = p.waitFor();

        refreshActionPerformed(evt);

    } catch (InterruptedException ex) {
        Logger.getLogger(mainFrame.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (IOException ex) {
        Logger.getLogger(mainFrame.class.getName()).log(Level.SEVERE, null, ex);
    } 

Now, what I would like to have happen is that the command

refreshActionPerformed(evt);

runs only after the batch file I called has finished executing. But right now, it runs immediately after the Command Prompt opens.

How do I fix this?

Matt R. Johnson
  • 783
  • 1
  • 7
  • 14
  • Be sure to read and implement *all* the advice of [When Runtime.exec() won't](http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html). Otherwise you will almost certainly experience the "won't". Also consider using a `ProcessBuilder` for 1.5+ & passing the arguments as an array. – Andrew Thompson Jun 22 '11 at 19:04
  • I read When Runtime.exec() won't, but frankly, I'm completely new to Java programming and I have no idea how to implement the advice of that article. – Matt R. Johnson Jun 22 '11 at 19:14

3 Answers3

29

I manged to find the answer elsewhere. To keep the initial process open until the batch file finished all you need is "/wait"

Process p = Runtime.getRuntime().exec("cmd /C start /wait filepath.bat");
int exitVal = p.waitFor();
cha0site
  • 10,517
  • 3
  • 33
  • 51
Matt R. Johnson
  • 783
  • 1
  • 7
  • 14
4

calling "cmd /c start" causes cmd to fire off another instance and exit immediately. Try taking out the "start" command.

Rocky Pulley
  • 22,531
  • 20
  • 68
  • 106
  • When I do this, my program freezes up. My guess is that p.waitfor() isn't returning now. What should I do? – Matt R. Johnson Jun 22 '11 at 18:42
  • maybe put an "exit" at the end of your .bat file? – Rocky Pulley Jun 22 '11 at 18:43
  • That seems to work. But my problem is that the contents of the .bat file are user defined. So if they don't put an EXIT at the end, they're kinda screwed. Any advice? – Matt R. Johnson Jun 22 '11 at 18:46
  • Yes, create a wrapper batch file, say MyFileExecutor.bat and in that you put the name of the file the user creates followed by exit. You can create and execute this file on the fly if you want. – Rocky Pulley Jun 22 '11 at 18:50
  • So MyFileExecutor.bat should CALL the user's bat? This still doesn't seem to work if the user's bat (or other bats called by the user's bat) doesn't have an EXIT statement. – Matt R. Johnson Jun 22 '11 at 18:59
  • There also seems to be trouble if the called bat file includes a PAUSE command. – Matt R. Johnson Jun 22 '11 at 20:00
  • if they put a pause in the bat file there is nothing you can do about it. Just like there is nothing you can do about it if they put a command do delete all of the files from the hard drive. You have to draw the line somewhere in what you can and can't support. When you are calling the other bat file, make sure you just type the name of the bat file on the line and don't try to call "cmd /c file.bat" inside your bat file, just do "file.bat". – Rocky Pulley Jun 23 '11 at 02:10
3

The answer given is correct. I added that the window opened by the code needs to be closed manually.

Process p = Runtime.getRuntime().exec("cmd /C start /wait filepath.bat");
int exitVal = p.waitFor();
Jeru Luke
  • 20,118
  • 13
  • 80
  • 87