Reputation: 946
I'm writing a simple Java Application where user can execute cmd commands. There is just a TextField to enter the command and a button to execute it. The code looks as follows:
sendButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", message.getText());
Process pr = pb.start();
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
Everything works fine if the user executes
notepad.exe
But for some reason I get the java.lang.IllegalArgumentException if the command is for example:
"C:\Users\Username\AppData\Local\Google\Chrome\Application\chrome.exe" www.youtube.com
It's probably because of the quotes, does anybody know a workaround for this?
Upvotes: 0
Views: 1236
Reputation: 124235
ProcessBuilder
expects list of arguments passed as List<String>
or String...
. Your problem is that you are passing two separate arguments as one because they have space not in quotes. So you need to split user command on spaces that are not placed in quotes. To do this you can use
Pattern p = Pattern.compile("\"[^\"]+\"|\\S+");
//pattern will find strings between quotes or separate words
Matcher m = p.matcher(userCmd);
while (m.find()) {
System.out.println("adding " + m.group());//just for debugging
list.add(m.group());
}
like in this example
String userCmd="\"C:\\Users\\Username\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe\""
+" www.youtube.com";
List<String> list=new ArrayList<>();
list.add("cmd.exe");
list.add("/c");
Pattern p = Pattern.compile("\"[^\"]+\"|\\S+");
Matcher m = p.matcher(userCmd);
while (m.find()) {
System.out.println("adding " + m.group());
list.add(m.group());
}
ProcessBuilder pb = new ProcessBuilder(list);
Process pr = pb.start();
InputStream err=pr.getErrorStream();
BufferedReader errReader=new BufferedReader(new InputStreamReader(err));
String line=null;
while((line=errReader.readLine())!=null){
System.out.println(line);
}
which in my case prints only error about not finding such path on my computer, but in user computer should work fine.
Upvotes: 4
Reputation: 8960
Well since you asked for a workaround, you could try trimming the quotes from the whole string before the builder runs it: message.getText().replaceAll("\"", "");
.
The downside is that you can have more complex cases where it's hard to figure out what to trim or not.
Upvotes: 0