ProcessBuilder为命令行添加了额外的引号

ste*_*wpf 10 java windows process processbuilder

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

"C:\Program Files\USBDeview\USBDeview.exe" /enable "My USB Device"
Run Code Online (Sandbox Code Playgroud)

我尝试使用以下代码:

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();   
Run Code Online (Sandbox Code Playgroud)

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

"C:\Program Files\USBDeview\USBDeview.exe" "/enable "My USB Device""
Run Code Online (Sandbox Code Playgroud)

请注意之前的引用/enable和之后的两个引号Device.我需要摆脱那些额外的引号,因为它们使调用失败.有谁知道如何做到这一点?

KJP*_*KJP 14

Joachim是正确的,但是当你的流程需要统一的参数时,他的答案是不够的:

myProcess.exe /myParameter="my value"
Run Code Online (Sandbox Code Playgroud)

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

myProcess.exe "/myParameter="my value""
Run Code Online (Sandbox Code Playgroud)

如Joachim建议的那样分解参数值将导致/myparameter=和之间的空格"my value",这对于这种类型的参数不起作用:

myProcess.exe /myParameter= "my value"
Run Code Online (Sandbox Code Playgroud)

根据Sun的说法,在他们的无限智慧中,它不是一个错误,双引号可以被转义以实现所期望的行为.

所以,为了最终回答stefan的问题,如果您调用的进程正确地执行了操作,那么这是一个应该可行的替代方法:

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

这应该给你命令"C:\Program Files\USBDeview\USBDeview.exe" "/enable \"My USB Device\"",这可能会做到这一点; 因人而异.

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

Joa*_*son 10

据我所知,由于ProcessBuilder不知道如何将参数传递给命令,因此您需要将参数分别传递给ProcessBuilder;

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


Ian*_*rts 5

首先,你需要自己拆分参数 - ProcessBuilder不要为你做这些 - 然后你不需要在参数值周围放置转义引号.

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

命令行上必须引用这些引号,以便告诉cmd解析器如何将单词分解为参数,但ProcessBuilder不需要它们,因为它已经被赋予了pre-split参数.