【问题标题】:IllegalArgumentException when executing command with ProcessBuilder in Java在 Java 中使用 ProcessBuilder 执行命令时出现 IllegalArgumentException
【发布时间】:2013-08-10 19:56:40
【问题描述】:

我正在编写一个简单的 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();
                }
            }
        });

如果用户执行,一切正常

notepad.exe

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

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

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

【问题讨论】:

  • 不带引号可以运行吗? IllegalArgumentException 基本上意味着 Command not found
  • 我可以在没有引号的情况下运行它。但理想情况下,应用程序应该能够运行可以在 cmd 本身中运行的所有命令。
  • 不,Exceprion 来自Process pr = pb.start();
  • 阅读(并实施)所有 When Runtime.exec() won't 的建议。那可能会解决问题。如果没有,它应该提供更多关于失败原因的信息。然后忽略它引用exec 并(继续)使用ProcessBuilder 构建Process。还要将String arg 分解为String[] args 以说明本身包含空格的参数。

标签: java processbuilder illegalargumentexception


【解决方案1】:

ProcessBuilder 期望以List<String>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);
}

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

【讨论】:

  • 它是否适用于您拥有的程序?我不确定它是否可以与引号一起使用,因为 ProcessBuilder 会转义路径,因此引号将作为文字传递。
  • @BoristheSpider 是的,如果我将路径更改为真实路径,它工作正常。
【解决方案2】:

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

缺点是您可能会遇到更复杂的情况,很难确定要修剪什么。

【讨论】:

  • 如果引号是有原因的,这肯定行不通。这不是一个可行的解决方案。
  • 我同意。根据定义,变通方法是不可行的解决方案
猜你喜欢
  • 2014-03-14
  • 2017-03-07
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 2012-03-11
  • 2023-03-11
  • 2017-05-27
  • 1970-01-01
相关资源
最近更新 更多