41

I tried to make an application that calls an external program that I have to pass two parameters. It doesn't give any errors.

The program.exe, written in C++, takes a picture and modifies the content of a .txt file.

The Java program runs but it does nothing-

Here is my sample code:

    String[] params = new String [3];
    params[0] = "C:\\Users\\user\\Desktop\\program.exe";
    params[1] = "C:\\Users\\user\\Desktop\\images.jpg";
    params[2] = "C:\\Users\\user\\Desktop\\images2.txt";
    Runtime.getRuntime().exec(params);
Lii
  • 11,553
  • 8
  • 64
  • 88
sqtd
  • 485
  • 1
  • 4
  • 6
  • 6
    What's the problem exactly, do you have an error message you can add to the question? Thanks. – Jonathan Dec 21 '12 at 13:27
  • you said, you want to pass two parameter, but here you are showing 3 parameters – Ravi Dec 21 '12 at 13:30
  • if *it does not* execute, what is the error ? what does your program.exe do ? – vels4j Dec 21 '12 at 13:31
  • 11
    Why is this question closed as "too localized"? – user886079 Nov 09 '15 at 15:54
  • Does this answer your question? [Java Programming: call an exe from Java and passing parameters](https://stackoverflow.com/questions/5604698/java-programming-call-an-exe-from-java-and-passing-parameters) – Dave Jarvis Apr 10 '21 at 22:05

5 Answers5

79

borrowed this shamely from here

Process process = new ProcessBuilder("C:\\PathToExe\\MyExe.exe","param1","param2").start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;

System.out.printf("Output of running %s is:", Arrays.toString(args));

while ((line = br.readLine()) != null) {
  System.out.println(line);
}

More information here

Other issues on how to pass commands here and here

Evan Knowles
  • 7,426
  • 2
  • 37
  • 71
Steven
  • 1,365
  • 2
  • 13
  • 28
  • 1
    my problem is to pass parameters to program.exe – sqtd Dec 21 '12 at 13:49
  • Apart from getInputStream you can use getErrorStream to get the error messages (stderr) – golimar Jan 13 '15 at 14:01
  • For people looking for the one-liner with parameters: `(new ProcessBuilder(new String[]{ notePadPath, theFile.getPath()})).start();` ... well... wrapped in a try/catch.... assuming `notePadPath` is something like `c:\\program files\\notepad++\\notepad++.exe` .. double slash for escape.. and your awesome because you use np++ – Pimp Trizkit Aug 25 '15 at 00:10
  • 1
    What is the "args" variable? – user64141 Apr 15 '16 at 19:46
15

You might also try its more modern cousin, ProcessBuilder:

Java Runtime.getRuntime().exec() alternatives

Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
duffymo
  • 305,152
  • 44
  • 369
  • 561
2
import java.io.*;

public class Code {
  public static void main(String[] args) throws Exception {
    ProcessBuilder builder = new ProcessBuilder("ls", "-ltr");
    Process process = builder.start();

    StringBuilder out = new StringBuilder();
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
        String line = null;
      while ((line = reader.readLine()) != null) {
        out.append(line);
        out.append("\n");
      }
      System.out.println(out);
    }
  }
}

Try online

Vishal
  • 19,879
  • 23
  • 80
  • 93
1

This version is a Java 17 version using some built in convenience functions like the xyzReader methods and the streaming API consumption of the output. Take note that the example works for programs not running long and returning immediately when ready, so no daemons (otherwise the output processing should be done in a thread while waiting for the process to exit.).

If all the exception handling is ignored the code is really short:

        Process process = new ProcessBuilder("program", "param1", "param2").start();
        // check your program's used exit code in case or error
        if (process.waitFor() != 0) {
            throw new IOException("Program failed.");
        }
        String out;
        try (BufferedReader reader = process.inputReader()) {
            out = reader.lines().collect(Collectors.joining());
        }

A more verbose version with proper error handling:

        Process process;
        try {
            process = new ProcessBuilder("myprogram", "param1",
                    "param2").start();
            int errorCode = process.waitFor();
// adjust the error code for your use case, different programs migth not use 0 as success
            if (errorCode != 0) {
                try (BufferedReader reader = process.errorReader(StandardCharsets.UTF_8)) {
                    throw new RuntimeException(String.format("Program execution failed (code %d): %s", errorCode,
                            reader.lines().collect(Collectors.joining())));
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("Could not invoke program.", e);
        } catch (InterruptedException e) {
            throw new RuntimeException("Could not wait for process exit.", e);
        }
        String output;
        try (BufferedReader reader = process.inputReader()) {
            output = reader.lines().collect(Collectors.joining());
        } catch (IOException e) {
            throw new RuntimeException("Could not invoke external program.", e);
        }

Also take into account that maybe not the inputReader is used for all output, but also the errorReader holds some information of the program output. It can also be that programs are using the inputReader for the error messages instead of the errorReader

k_o_
  • 5,143
  • 1
  • 34
  • 43
  • Note that this version blocks on `waitFor` if process produces some output. ([more info](https://stackoverflow.com/a/36740811/653539) - happened to me with `git status` launched this way) – Tomáš Záluský May 23 '23 at 14:41
0

new ProcessBuilder("command").inheritIO().start().waitFor();

explanation:

ProcessBuilder pb = new ProcessBuilder("command");

"command": like "ls"(ls command if platform supports) or "javac"(if java is installed) or "notepad" or "ping" complete path to an specific program ("path\to\autocad.exe")

Now you have a process builder ready.

Next you instruct that instead of dealing with all aspects relevant to input output programmatically, just you prefer to have the I/O in current terminal as usually you do in windows/linux terminal:

.inheritIO();

Now your process builder is even more ready.

Now you have to practically make the process via:

.start()

Now, the process is in execution, in parallel to your java program. Opposite to an ordinary way of execution of every instruction of a program that are sequentially. That means the computer won't finish that process and then go to the next instruction of your java program, and before finishing that process, further lines of code will be executed (concurrent programming, multithreading).

If you don't want that to happen, then you have to mention it via: waitFor();

Maj
  • 29
  • 4
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 24 '22 at 18:03