0

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?

4
  • Can you run it without the quotes? The IllegalArgumentException basically means Command not found. Commented Aug 10, 2013 at 11:16
  • I can run it without the quotes. But ideally the Application should be able to run all of the commands that can be run in the cmd itself. Commented Aug 10, 2013 at 11:19
  • No, the Exceprion is coming from the Process pr = pb.start(); Commented Aug 10, 2013 at 11:31
  • Read (and implement) all the recommendations of When Runtime.exec() won't. That might solve the problem. If not, it should provide more information as to the reason it failed. Then ignore that it refers to exec and (continue to) build the Process using a ProcessBuilder. Also break a String arg into String[] args to account for arguments which themselves contain spaces. Commented Aug 10, 2013 at 11:32

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Does it work with a program you do have? I'm not sure it will work with the quotes as the ProcessBuilder escapes the path so the quotes would be passed as literals.
@BoristheSpider Yes if I change path to real one it works fine.
0

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.

2 Comments

Surely this won't work if the quotes are there for a reason. This isn't a workable solution.
I agree. Workarounds are by definition not viable solutions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.