0

我正在编写一个简单的 Java 应用程序,用户可以在其中执行 cmd 命令。只有一个 TextField 输入命令和一个按钮来执行它。代码如下所示:

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();
                }
            }
        });

如果用户执行,一切正常

记事本.exe

但是由于某种原因,如果命令是例如,我会得到java.lang.IllegalArgumentException :

"C:\Users\Username\AppData\Local\Google\Chrome\Application\chrome.exe" www.youtube.com

这可能是因为引号,有人知道解决方法吗?

4

2 回答 2

4

ProcessBuilderList<String>期望作为or传递的参数列表String...。您的问题是您将两个单独的参数作为一个参数传递,因为它们的空格不在引号中。因此,您需要在未放在引号中的空格上拆分用户命令。为此,您可以使用

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());
}

就像在这个例子中

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);
}

在我的情况下,仅打印关于在我的计算机上找不到此类路径的错误,但在用户计算机中应该可以正常工作。

于 2013-08-10T11:32:35.860 回答
0

好吧,既然您要求解决方法,您可以尝试在构建器运行它之前从整个字符串中修剪引号:message.getText().replaceAll("\"", "");.

不利的一面是,您可能会遇到更复杂的情况,很难弄清楚要修剪什么。

于 2013-08-10T11:27:03.360 回答