【问题标题】:java ProcessBuilder in Windows spaces in *.exe path and in argument*.exe 路径和参数中的 Windows 空间中的 java ProcessBuilder
【发布时间】:2021-05-08 18:32:58
【问题描述】:

经常讨论,但这似乎是一个奇怪的边缘案例。

在win cmd.exe中我成功运行:

"c:\Program Files\myapp.exe" -my_arg="sth. with space"

"c:\Program Files\myapp.exe" -my_arg="sth_without_space"

在 java ProcessBuilder.command(xxx) 中,以下失败,“c:\Program”不是有效命令(xxx 包含以下数组):

// using cmd.exe:
["cmd.exe", "/c", "c:\Program Files\myapp.exe", "-my_arg=sth. with space"]         // no extra quoting
["cmd.exe", "/c", "\"c:\Program Files\myapp.exe\"", "-my_arg=sth. with space"]     // exe       quoted
["cmd.exe", "/c", "\"c:\Program Files\myapp.exe\"", "-my_arg=\"sth. with space\""] // exe & arg quoted
["cmd.exe", "/c", "c:\Program Files\myapp.exe", "-my_arg=\"sth. with space\""]     //       arg quoted

// putting all as cmd.exe arg:
["cmd.exe", "/c", "c:\Program Files\myapp.exe -my_arg=sth. with space"]            // no extra quoting
["cmd.exe", "/c", "\"c:\Program Files\myapp.exe\" -my_arg=sth. with space"]        // exe       quoted
["cmd.exe", "/c", "\"c:\Program Files\myapp.exe\" -my_arg=\"sth. with space\""]    // exe & arg quoted
["cmd.exe", "/c", "c:\Program Files\myapp.exe -my_arg=\"sth. with space\""]        //       arg quoted

// calling *.exe directly
["c:\Program Files\myapp.exe", "-my_arg=sth. with space"]                          // no extra quoting
["\"c:\Program Files\myapp.exe\"", "-my_arg=sth. with space"]                      // exe       quoted
["\"c:\Program Files\myapp.exe\"", "-my_arg=\"sth. with space\""]                  // exe & arg quoted
["c:\Program Files\myapp.exe", "-my_arg=\"sth. with space\""]                      //       arg quoted

运行正常:

["cmd.exe", "/c", "c:\Program Files\myapp.exe", "-my_arg=sth_without_space"]

当 *.exe 路径和 arg 包含空格时,问题似乎就开始了。

[编辑]: 我的问题是:如何在 exe 的路径和 arg 的内容中使用空格来运行它?

【问题讨论】:

  • *.com/questions/16639285/… 它适用于 cmd,因为您将正确格式化字符串的工作传递给 cmd 本身。
  • 它只在 arg 中不带空格的情况下工作 - 但如何让它在带空格的情况下工作?

标签: java windows command-line processbuilder


【解决方案1】:

要使其与 cmd 和 WITH 空格一起工作,您需要添加另一层引用。

毕竟你写了一个java程序。 java 编译器将期望字符串被引用,但在运行时这些引号不再存在。一些字符串将用于启动 cmd,其他将传递给 cmd。

Cmd 本身会检查它收到的参数并解析它们。要标记哪个空格是分隔符,哪个不是,您需要使用引号。 Cmd 将理解这些引号并删除它们 - 被调用的程序不再注意到它们。

所以要么添加更多引号(正确转义),要么尝试直接运行可执行文件。

["cmd.exe", "/c", "\"c:\\Program Files\\myapp.exe\"", "\"-my_arg=sth_with space\""]

【讨论】:

  • 在您的机器上进行了这项锻炼吗?在我的它响应:'c:\Program' is not recognized as an internal or external command, operable program or batch file. running cmd -h 响应:Microsoft Windows [Version 10.0.18363.1256](c) 2019 Microsoft Corporation. All rights reserved. 而我的 java 是:openjdk version "14.0.2" 2020-07-14
  • 我刚刚遇到了这个问题:您可以直接运行["*.exe"],而无需预先设置["cmd.exe", "/c"]——甚至根本不需要引用。但是:这仅适用于 *.exe。如果您的目标是同时运行 foo.bat 并将带有空格的 args 传递给它,则它不起作用。
  • 我发现您还想转义反斜杠,因此 java 编译器不必抱怨(有趣的是它不适合您)。如果你坚持它仍然抱怨找不到 C:/Program,你需要再引用一次。