Viet
Viet

Reputation: 3409

How to get commandLine & arguments of Process in Java 9

Java 9 provied pretty way to get information of the Process, but I still don't know how to get the CommandLine & arguments of the process:

Process p = Runtime.getRuntime().exec("notepad.exe E:\\test.txt");
ProcessHandle.Info info = p.toHandle().info();
String[] arguments = info.arguments().orElse(new String[]{});
System.out.println("Arguments : " + arguments.length);
System.out.println("Command : " + info.command().orElse("")); 
System.out.println("CommandLine : " + info.commandLine().orElse(""));

Result:

Arguments : 0
Command : C:\Windows\System32\notepad.exe
CommandLine : 

But I am expecting:

Arguments : 1
Command : C:\Windows\System32\notepad.exe
CommandLine : C:\Windows\System32\notepad.exe E:\\test.txt

Upvotes: 17

Views: 2978

Answers (3)

Gili
Gili

Reputation: 90180

JDK-8176725 indicates that this feature is not implemented yet for Windows. Here is an easy but slow workaround:

  /**
   * Returns the full command-line of the process.
   * <p>
   * This is a workaround for
   * <a href="https://stackoverflow.com/a/46768046/14731">https://stackoverflow.com/a/46768046/14731</a>
   *
   * @param processHandle a process handle
   * @return the command-line of the process
   * @throws UncheckedIOException if an I/O error occurs
   */
  private Optional<String> getCommandLine(ProcessHandle processHandle) throws UncheckedIOException {
    if (!isWindows) {
      return processHandle.info().commandLine();
    }
    long desiredProcessid = processHandle.pid();
    try {
      Process process = new ProcessBuilder("wmic", "process", "where", "ProcessID=" + desiredProcessid, "get",
        "commandline", "/format:list").
        redirectErrorStream(true).
        start();
      try (InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());
           BufferedReader reader = new BufferedReader(inputStreamReader)) {
        while (true) {
          String line = reader.readLine();
          if (line == null) {
            return Optional.empty();
          }
          if (!line.startsWith("CommandLine=")) {
            continue;
          }
          return Optional.of(line.substring("CommandLine=".length()));
        }
      }
    } catch (IOException e) {
      throw new UncheckedIOException(e);
    }
  }

Upvotes: 5

Mykola Yashchenko
Mykola Yashchenko

Reputation: 5371

Try to use ProcessBuilder instead of Runtime#exec()

Process p = new ProcessBuilder("notepad.exe", "E:\\test.txt").start();

Or another way to create a process :

Process p = Runtime.getRuntime().exec(new String[] {"notepad.exe", "E:\\test.txt"});

Upvotes: 1

M A
M A

Reputation: 72884

Seems this was reported in JDK-8176725. Here is the comment describing the issue:

The command line arguments are not available via a non-privileged API for other processes and so the Optional is always empty. The API is explicit that the values are OS specific. If in the future, the arguments are available by a Window APIs, the implementation can be updated.

BTW, the info structure is filled by native code; the assignments to the fields do not appear in the Java code.

Upvotes: 12

Related Questions