Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top