【问题标题】:ProcessBuilder adds extra quotes to command lineProcessBuilder 向命令行添加额外的引号
【发布时间】:2012-08-20 22:26:16
【问题描述】:

我需要使用 ProcessBuilder 构建以下命令:

"C:\Program Files\USBDeview\USBDeview.exe" /enable "My USB Device"

我尝试了以下代码:

ArrayList<String> test = new ArrayList<String>();
test.add("\"C:\\Program Files\\USBDeview\\USBDeview.exe\"");
test.add("/enable \"My USB Device\"");  

ProcessBuilder processBuilder = new ProcessBuilder(test);                       
processBuilder.start().waitFor();   

但是,这会将以下内容传递给系统(使用 Sysinternals Process Monitor 验证)

"C:\Program Files\USBDeview\USBDeview.exe" "/enable "My USB Device""

注意/enable 之前的引号和Device 之后的两个引号。我需要去掉那些额外的引号,因为它们会使调用失败。有谁知道怎么做?

【问题讨论】:

  • 很好的观察!是否有任何文档描述 ProcessBuilder 用双引号引用每个参数?

标签: java windows process processbuilder


【解决方案1】:

Joachim 是正确的,但当您的流程需要如下统一参数时,他的答案是不充分的:

myProcess.exe /myParameter="my value"

正如 stefan 所见,ProcessBuilder 会在您的参数中看到空格并将其括在引号中,如下所示:

myProcess.exe "/myParameter="my value""

按照 Joachim 的建议拆分参数值会导致在 /myparameter="my value" 之间出现空格,这不适用于此类参数:

myProcess.exe /myParameter= "my value"

根据 Sun 的说法,在他们的 infinite wisdom 中,这不是一个错误,而是用双引号 can be escaped 来实现所需的行为。

所以最后回答 stefan 的问题,如果您调用的进程正确执行,这是一个应该有效的替代方法:

ArrayList<String> test = new ArrayList<String>();
test.add("\"C:\\Program Files\\USBDeview\\USBDeview.exe\"");
test.add("/enable \\\"My USB Device\\\"");

这应该会给你命令"C:\Program Files\USBDeview\USBDeview.exe" "/enable \"My USB Device\"",这可能会奏效; YMMV。

【讨论】:

  • 您是否曾找到过官方参考资料指出 ProcessBuilder 将“在您的论点中看到空格并用引号括起来”?我可以从我的测试中确认这一点,但是,没有任何 JavaDoc 声明过(或者至少没有我能找到),这太疯狂了。不错的答案!
【解决方案2】:

据我了解,由于 ProcessBuilder 不知道如何将参数传递给命令,因此您需要将参数单独传递给 ProcessBuilder;

ArrayList<String> test = new ArrayList<String>();
test.add("\"C:\\Program Files\\USBDeview\\USBDeview.exe\"");
test.add("/enable");
test.add("\"My USB Device\"");

【讨论】:

  • 谢谢 Joachim,你是对的。我得到额外引号的原因是启用和“我的...”之间的空格。像你想象的那样拆分它是有效的。当我从 XML 文件中读取完整的命令时,解析现在变得有点复杂,但这是另一回事 ;-)
【解决方案3】:

首先,您需要自己拆分参数 - ProcessBuilder 不会为您这样做 - 其次,您不需要在参数值周围加上转义引号。

ArrayList<String> test = new ArrayList<String>();
test.add("C:\\Program Files\\USBDeview\\USBDeview.exe");
test.add("/enable");
test.add("My USB Device");

为了告诉 cmd 解析器如何将单词分解为参数,命令行中需要引号,但 ProcessBuilder 不需要它们,因为它已经预先分配了参数。

【讨论】:

    【解决方案4】:

    我无法让它以上述任何方式工作。我最终将命令写入一个单独的脚本(每个空格都使用“\”)并将其写入脚本文件,然后调用脚本文件。

    【讨论】:

      猜你喜欢
      • 2020-11-16
      • 2012-01-13
      • 1970-01-01
      • 2022-09-24
      • 1970-01-01
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多