简体   繁体   English

如何在Java 9中获取Process的commandLine和参数

[英]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: Java 9提供了获取Process信息的漂亮方法,但我仍然不知道如何获取该进程的CommandLinearguments

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

Seems this was reported in JDK-8176725 . 似乎这是在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. 对于其他进程,命令行参数不能通过非特权API使用,因此Optional始终为空。 The API is explicit that the values are OS specific. API明确指出值是特定于操作系统的。 If in the future, the arguments are available by a Window APIs, the implementation can be updated. 如果将来可以通过Window API获得参数,则可以更新实现。

BTW, the info structure is filled by native code; 顺便说一句,信息结构由本机代码填充; the assignments to the fields do not appear in the Java code. 字段的分配不会出现在Java代码中。

Try to use ProcessBuilder instead of Runtime#exec() 尝试使用ProcessBuilder而不是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"});

JDK-8176725 indicates that this feature is not implemented yet for Windows. JDK-8176725表示尚未为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);
    }
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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