Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中使用ProcessBuilder执行命令时发生IllegalArgumentException_Java_Processbuilder_Illegalargumentexception - Fatal编程技术网

在Java中使用ProcessBuilder执行命令时发生IllegalArgumentException

在Java中使用ProcessBuilder执行命令时发生IllegalArgumentException,java,processbuilder,illegalargumentexception,Java,Processbuilder,Illegalargumentexception,我正在编写一个简单的Java应用程序,用户可以在其中执行cmd命令。只有一个输入命令的文本字段和一个执行命令的按钮。代码如下所示: sendButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { ProcessBuil

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

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

但是由于某种原因,如果命令是例如:

“C:\Users\Username\AppData\Local\Google\Chrome\Application\Chrome.exe” www.youtube.com


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

既然您要求解决方法,您可以在生成器运行它之前尝试从整个字符串中删除引号:
message.getText().replaceAll(“\”,”);


缺点是,您可能会遇到更复杂的情况,很难确定要修剪或不修剪哪些内容。

既然您要求解决问题,您可以尝试在生成器运行整个字符串之前修剪整个字符串的引号:
message.getText().replaceAll(“\”,”)


缺点是,在更复杂的情况下,很难确定要修剪或不修剪什么。

ProcessBuilder
需要作为
list
字符串传递的参数列表…
。您的问题是,您将两个单独的参数作为一个参数传递,因为它们在引号中没有空格。因此,您需要在未加引号的空格上拆分用户命令。要做到这一点,您可以使用

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);
}
String userCmd=“\”C:\\Users\\Username\\AppData\\Local\\Google\\Chrome\\Application\\Chrome.exe”
+“www.youtube.com”;
列表=新的ArrayList();
添加(“cmd.exe”);
列表。添加(“/c”);
模式p=Pattern.compile(“\”[^\“]+\“\\\S+”);
Matcher m=p.Matcher(userCmd);
while(m.find()){
System.out.println(“添加”+m.group());
list.add(m.group());
}
ProcessBuilder pb=新的ProcessBuilder(列表);
进程pr=pb.start();
InputStream err=pr.getErrorStream();
BufferedReader errReader=新的BufferedReader(新的InputStreamReader(err));
字符串行=null;
而((line=errReader.readLine())!=null){
系统输出打印项次(行);
}

在我的例子中,它只打印关于在我的计算机上找不到这样的路径的错误,但在用户计算机上应该可以正常工作。

ProcessBuilder
需要作为
list
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);
}
String userCmd=“\”C:\\Users\\Username\\AppData\\Local\\Google\\Chrome\\Application\\Chrome.exe”
+“www.youtube.com”;
列表=新的ArrayList();
添加(“cmd.exe”);
列表。添加(“/c”);
模式p=Pattern.compile(“\”[^\“]+\“\\\S+”);
Matcher m=p.Matcher(userCmd);
while(m.find()){
System.out.println(“添加”+m.group());
list.add(m.group());
}
ProcessBuilder pb=新的ProcessBuilder(列表);
进程pr=pb.start();
InputStream err=pr.getErrorStream();
BufferedReader errReader=新的BufferedReader(新的InputStreamReader(err));
字符串行=null;
而((line=errReader.readLine())!=null){
系统输出打印项次(行);
}

在我的例子中,它只打印关于在我的计算机上找不到这样的路径的错误,但在用户计算机中应该可以正常工作。

您能在没有引号的情况下运行它吗?
IllegalArgumentException
基本上意味着找不到命令。我可以在没有引号的情况下运行它。但理想情况下,应用程序应该能够运行可以在cmd本身中运行的所有命令阅读(并实施)的所有建议。这可能会解决问题。如果没有,它应该提供更多关于失败原因的信息。然后忽略它引用的
exec
,并(继续)使用
ProcessBuilder
构建
流程。还可以将
String arg
分解为
String[]args
,以说明本身包含空格的参数。是否可以在不使用引号的情况下运行它?
IllegalArgumentException
基本上意味着找不到命令。我可以在没有引号的情况下运行它。但理想情况下,应用程序应该能够运行可以在cmd本身中运行的所有命令阅读(并实施)的所有建议。这可能会解决问题。如果没有,它应该提供更多关于失败原因的信息。然后忽略它引用的
exec
,并(继续)使用
ProcessBuilder
构建
流程。还可以将
字符串arg
分解为
字符串[]args
,以说明本身包含空格的参数。如果引号是出于某种原因而存在,那么这肯定不起作用。这不是一个可行的解决办法,我同意。根据定义,变通办法不是可行的解决方案。如果引用是有原因的,那么这肯定行不通。这不是一个可行的解决办法,我同意。根据定义,变通办法是不可行的解决方案。它是否适用于您现有的程序?我不确定它是否能与引号一起工作,因为
ProcessBuilder
会转义路径,因此引号将作为文本传递。@BoriseSteider是的,如果我将路径更改为真实路径,它可以正常工作。它能与您的程序一起工作吗?我不确定它是否能与引号一起工作,因为
ProcessBuilder
会转义路径,因此引号将作为文本传递。@BoristheSpider是的,如果我将路径更改为真实路径,它会正常工作。