2012-08-25 55 views
8

我需要使用的ProcessBuilder建立以下命令:的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"" 

請注意之前的報價和Device後的兩個引號。我需要擺脫這些額外的引號,因爲它們會導致調用失敗。有誰知道如何做到這一點?

+0

不錯的觀察!是否有任何文檔描述了ProcessBuilder用雙引號引用每個參數? – okwap

回答

8

據我所知,由於ProcessBuilder不知道如何將參數傳遞給該命令,因此需要將參數單獨傳遞給ProcessBuilder;

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

謝謝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並不需要它們,因爲它已經被給定的參數預裂。

10

約阿希姆是正確的,但是當你的過程中預計的統一參數如下他的回答是不夠的:

myProcess.exe /myParameter="my value" 

正如斯特凡看到的ProcessBuilder會看到你的論點空間,敷在引號,像這樣:

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

分手的參數值作爲勒夫建議將導致/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\"",這可能做的伎倆;因人而異。

+1

您是否曾經發現過一個官方參考,指出ProcessBuilder將「看到您的參數中的空格並用引號「?我可以從我的測試中證實,但是,沒有任何JavaDoc聲明(或者至少沒有我能找到的)是瘋狂的。很好的答案! – mateuscb