37

我正在用 java 编写一个程序,它将执行 winrar 并将我的 jar 文件解压缩h:\myjar.jar到文件夹h:\new中。我的java代码是这样的

import java.io.File;
import java.io.IOException;

public class MainClass {

    public static void main(String[] args) {

        Runtime r = Runtime.getRuntime();
        Process p = null;

        try {
            File dir = new File("C:/Program Files/WinRAR");
            p = r.exec("winrar x h:\\myjar.jar *.* h:\\new", null, dir);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

当我执行此操作时,我收到此错误

java.io.IOException: Cannot run program "winrar" (in directory "C:\Program Files\WinRAR"): CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessBuilder.start(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at MainClass.main(MainClass.java:16)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(Unknown Source)
    at java.lang.ProcessImpl.start(Unknown Source)
    ... 4 more

谁能告诉我为什么会遇到这样的问题。我需要在代码中进行哪些更改才能使其正常工作?

4

6 回答 6

46

假设它winrar.exePATH, thenRuntime.exec能够找到它,如果不是,您将需要提供它的完全限定路径,例如,假设winrar.exe安装在C:/Program Files/WinRAR您将需要使用类似...

p=r.exec("C:/Program Files/WinRAR/winrar x h:\\myjar.jar *.* h:\\new");

就个人而言,我建议您使用它,ProcessBuilder因为它具有一些额外的配置功能。在可能的情况下,您还应该将命令和参数分成单独的String元素,它比单个变量更好地处理诸如空格之类的事情String,例如...

ProcessBuilder pb = new ProcessBuilder(
    "C:/Program Files/WinRAR/winrar",
    "x",
    "myjar.jar",
    "*.*",
    "new");
pb.directory(new File("H:/"));
pb. redirectErrorStream(true);

Process p = pb.start();

不要忘记InputStream从进程中读取内容,否则可能会停止进程

于 2013-10-27T20:23:19.717 回答
23

我使用了 ProcessBuilder 但遇到了同样的问题。问题在于使用命令作为一个字符串行(就像我在 cmd 中键入它一样)而不是字符串数组。在上面的例子中。如果我跑

ProcessBuilder pb = 
   new ProcessBuilder("C:/Program Files/WinRAR/winrar x myjar.jar *.* new");
pb.directory(new File("H:/"));
pb.redirectErrorStream(true);

Process p = pb.start();

我有一个错误。但如果我跑

ProcessBuilder pb = 
   new ProcessBuilder("C:/Program Files/WinRAR/winrar", "x", "myjar.jar", "*.*", "new");
pb.directory(new File("H:/"));
pb.redirectErrorStream(true);

Process p = pb.start();

一切都很好。

于 2016-11-17T07:20:05.647 回答
14

您指定的dir是正在运行的进程的工作目录 - 它无助于查找可执行文件。用于运行在PATHcmd /c winrar ...中寻找可执行文件的进程或尝试使用winrar的绝对路径。

于 2013-10-27T19:27:44.143 回答
3

的完整第一个参数exec被解释为可执行文件。采用

p = rt.exec(new String[] {"winrar.exe", "x", "h:\\myjar.jar", "*.*", "h:\\new" }
            null, 
            dir);
于 2013-10-27T18:38:15.997 回答
2

我的建议是保留getRuntime().exec因为exec使用ProcessBuilder.

尝试

 p=r.exec(new String[] {"winrar", "x", "h:\\myjar.jar", "*.*", "h:\\new"}, null, dir);
于 2017-02-06T11:47:39.523 回答
0

无论哪种方式都对我有用:Runtime.getRuntime().exec(...) 或使用 ProcessBuilder。仍然对于某些调用,它仍然失败,并出现与原始问题中所述相同的错误:“CreateProcess error=2,系统找不到指定的文件”。仔细检查,那是因为我正在执行一个使用当前目录引用 (%~dp0) 的命令文件。显然,即使从同一目录调用命令,它们也不起作用。使用绝对路径解决了这个问题。

于 2021-12-07T14:01:34.193 回答