119

In my Java application, I want to run a batch file that calls "scons -Q implicit-deps-changed build\file_load_type export\file_load_type"

It seems that I can't even get my batch file to execute. I'm out of ideas.

This is what I have in Java:

Runtime.
   getRuntime().
   exec("build.bat", null, new File("."));

Previously, I had a Python Sconscript file that I wanted to run but since that didn't work I decided I would call the script via a batch file but that method has not been successful as of yet.

Nathan
  • 8,093
  • 8
  • 50
  • 76
Amara
  • 13,839
  • 9
  • 32
  • 28

12 Answers12

191

Batch files are not an executable. They need an application to run them (i.e. cmd).

On UNIX, the script file has shebang (#!) at the start of a file to specify the program that executes it. Double-clicking in Windows is performed by Windows Explorer. CreateProcess does not know anything about that.

Runtime.
   getRuntime().
   exec("cmd /c start \"\" build.bat");

Note: With the start \"\" command, a separate command window will be opened with a blank title and any output from the batch file will be displayed there. It should also work with just `cmd /c build.bat", in which case the output can be read from the sub-process in Java if desired.

Nathan
  • 8,093
  • 8
  • 50
  • 76
Paulo Guedes
  • 7,189
  • 5
  • 40
  • 60
  • For me it says Windows cannot find "build.bat". So where should I put this file? Or how should I give the path. Any suggestions? – nanospeck Jul 14 '14 at 08:38
  • 1
    lets say I have an array of commands and then iterating that array to execute all the commands for(i=0 to commands.length){ Runtime.getRuntime().exec("cmd /c start buil.bat"); } then for every iteration(for every command) a command window is getting opened which is obvious. How can avoid that I mean executing all the commands on one window. – viveksinghggits Jun 28 '16 at 08:24
  • 1
    We have some code which is directly calling "gradlew.bat" without putting "cmd /c" stuff in front of it, and that code is working somehow. So I guess either Java or Windows fixed part of the problem at some point. If we try to exec "gradlew", that fails though, so clearly the ".bat" is still needed on the end. – Hakanai Sep 26 '17 at 06:52
  • `Win+R` (Runtime) can execute batch files directly. – Alex78191 Nov 22 '18 at 23:42
23

Sometimes the thread execution process time is higher than JVM thread waiting process time, it use to happen when the process you're invoking takes some time to be processed, use the waitFor() command as follows:

try{    
    Process p = Runtime.getRuntime().exec("file location here, don't forget using / instead of \\ to make it interoperable");
    p.waitFor();

}catch( IOException ex ){
    //Validate the case the file can't be accesed (not enought permissions)

}catch( InterruptedException ex ){
    //Validate the case the process is being stopped by some external situation     

}

This way the JVM will stop until the process you're invoking is done before it continue with the thread execution stack.

Sled
  • 18,541
  • 27
  • 119
  • 168
20
Runtime runtime = Runtime.getRuntime();
try {
    Process p1 = runtime.exec("cmd /c start D:\\temp\\a.bat");
    InputStream is = p1.getInputStream();
    int i = 0;
    while( (i = is.read() ) != -1) {
        System.out.print((char)i);
    }
} catch(IOException ioException) {
    System.out.println(ioException.getMessage() );
}
cdeszaq
  • 30,869
  • 25
  • 117
  • 173
Isha
  • 201
  • 2
  • 2
  • 2
    It would be useful to comment this code and tell us why and what the InputStream is reading, and why I care. Also, the code for the batch file is running nicely, but I cannot get it to raise an error Exception. – Baruch Atta Jul 12 '17 at 17:58
  • 2
    It'd drive me nuts to have such a confusing variable name as "is" in my code. – John Fisher Sep 06 '17 at 21:55
14

To run batch files using java if that's you're talking about...

String path="cmd /c start d:\\sample\\sample.bat";
Runtime rn=Runtime.getRuntime();
Process pr=rn.exec(path);`

This should do it.

cspolton
  • 4,495
  • 4
  • 26
  • 34
Abbia
  • 141
  • 1
  • 2
  • 11
    The question was already answered with a working solution. You should offer only solutions you know are working and describe why you think your solution might be better. – Smamatti Oct 10 '12 at 18:21
14

ProcessBuilder is the Java 5/6 way to run external processes.

basszero
  • 29,624
  • 9
  • 57
  • 79
  • 2
    Why is the ProcessBuilder the way to go in Java 5/6? – Dan Polites Jan 10 '10 at 22:57
  • 2
    Interesting choice to resurrect an old post ... ProcessBuilder offers more control, specifically the ability to easily redirect stderr to stdout. I also find the setup more intuitive, but that's a personal pref – basszero Jan 11 '10 at 11:52
11

The executable used to run batch scripts is cmd.exe which uses the /c flag to specify the name of the batch file to run:

Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "build.bat"});

Theoretically you should also be able to run Scons in this manner, though I haven't tested this:

Runtime.getRuntime().exec(new String[]{"scons", "-Q", "implicit-deps-changed", "build\file_load_type", "export\file_load_type"});

EDIT: Amara, you say that this isn't working. The error you listed is the error you'd get when running Java from a Cygwin terminal on a Windows box; is this what you're doing? The problem with that is that Windows and Cygwin have different paths, so the Windows version of Java won't find the scons executable on your Cygwin path. I can explain further if this turns out to be your problem.

Eli Courtwright
  • 186,300
  • 67
  • 213
  • 256
  • Thank you. It still doesn't work - that piece of code doesn't even execute in my app. I'll try the other option you presented. Thanks again. – Amara Mar 05 '09 at 18:34
  • When I try the second alternative it gives me this error: Exception in thread "main" java.io.IOException: Cannot run program "scons": CreateProcess error=2, The system cannot find the file specified – Amara Mar 05 '09 at 18:37
  • No I don't have Cygwin terminal. I use Windows Command terminal. It's strange - I don't know why it wouldn't work. It completely baffles me. – Amara Mar 05 '09 at 18:54
5
Process p = Runtime.getRuntime().exec( 
  new String[]{"cmd", "/C", "orgreg.bat"},
  null, 
  new File("D://TEST//home//libs//"));

tested with jdk1.5 and jdk1.6

This was working fine for me, hope it helps others too. to get this i have struggled more days. :(

keshlam
  • 7,931
  • 2
  • 19
  • 33
Suren
  • 51
  • 1
  • 1
  • 1
    add this ==> BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); String line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } – Suren Jun 13 '13 at 12:39
2

I had the same issue. However sometimes CMD failed to run my files. That's why i create a temp.bat on my desktop, next this temp.bat is going to run my file, and next the temp file is going to be deleted.

I know this is a bigger code, however worked for me in 100% when even Runtime.getRuntime().exec() failed.

// creating a string for the Userprofile (either C:\Admin or whatever)
String userprofile = System.getenv("USERPROFILE");

BufferedWriter writer = null;
        try {
            //create a temporary file
            File logFile = new File(userprofile+"\\Desktop\\temp.bat");   
            writer = new BufferedWriter(new FileWriter(logFile));

            // Here comes the lines for the batch file!
            // First line is @echo off
            // Next line is the directory of our file
            // Then we open our file in that directory and exit the cmd
            // To seperate each line, please use \r\n
            writer.write("cd %ProgramFiles(x86)%\\SOME_FOLDER \r\nstart xyz.bat \r\nexit");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // Close the writer regardless of what happens...
                writer.close();
            } catch (Exception e) {
            }

        }

        // running our temp.bat file
        Runtime rt = Runtime.getRuntime();
        try {

            Process pr = rt.exec("cmd /c start \"\" \""+userprofile+"\\Desktop\\temp.bat" );
            pr.getOutputStream().close();
        } catch (IOException ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);

        }
        // deleting our temp file
        File databl = new File(userprofile+"\\Desktop\\temp.bat");
        databl.delete();
Ben Jost
  • 309
  • 1
  • 3
  • 10
1

The following is working fine:

String path="cmd /c start d:\\sample\\sample.bat";
Runtime rn=Runtime.getRuntime();
Process pr=rn.exec(path);
Prasad Khode
  • 6,602
  • 11
  • 44
  • 59
bharath
  • 11
  • 1
1
import java.io.IOException;

public class TestBatch {

    public static void main(String[] args) {
        {
            try {
                String[] command = {"cmd.exe", "/C", "Start", "C:\\temp\\runtest.bat"};
                Process p =  Runtime.getRuntime().exec(command);           
            } catch (IOException ex) {
            }
        }

    }

}
taing hong
  • 33
  • 1
  • 7
  • Please don't post only code as an answer, but also provide an explanation of what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes. – Ran Marciano Mar 24 '21 at 19:38
0

This code will execute two commands.bat that exist in the path C:/folders/folder.

Runtime.getRuntime().exec("cd C:/folders/folder & call commands.bat");
-1

To expand on @Isha's anwser you could just do the following to get the returned output (post-facto not in rea-ltime) of the script that was run:

try {
    Process process = Runtime.getRuntime().exec("cmd /c start D:\\temp\\a.bat");
    System.out.println(process.getText());
} catch(IOException e) {
    e.printStackTrace();
}
rolling_codes
  • 15,174
  • 22
  • 76
  • 112