CreateProcess错误=2,系统找不到指定的文件。

38
我正在编写一个Java程序,它可以执行Winrar并将放在h:\myjar.jar中的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

有人能告诉我为什么会遇到这样的问题吗?我需要在代码中做出哪些更改才能使其正常工作?

6个回答

51
假设winrar.exePATH中,那么Runtime.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 的内容,否则可能会导致进程停滞。


我的情况是,我在Windows系统变量中将该可执行文件的路径放入bin中。 - shareef
我使用 Python.exe 的完整路径运行了 Python 代码。谢谢。 - visrahane

29

我使用了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();

一切都很好。


1
这对我有用。关键是 pb.directory(...) 语句。正如下面其他人提到的,一旦你这样做了,你只需要将 exe 的名称作为第一个命令参数即可。我还必须像这样使用 cmd /cList<String> params = Arrays.asList("cmd", "/c", "quack1.exe", "inputfile.txt", "param1", "param2", "A"); ProcessBuilder pb = new ProcessBuilder(params); pb.directory(new File("C:/dev/test")); Process pr = (pb).start(); - Chris Clark

16
您指定的dir是运行进程的工作目录 - 它不能帮助找到可执行文件。使用cmd /c winrar ...运行进程,在PATH中查找可执行文件,或尝试使用绝对路径winrar

请问可以告诉我如何查看绝对路径的命令吗? - Trijit
p = rt.exec(new String[] {"C:\Program Files\WinRAR\winrar.exe", "x", "h:\myjar.jar", ".", "h:\new" } null, dir);...我仍然得到相同的错误。 - Trijit
如果您执行 rt.exec(new String[] {"cmd", "/c", "winrar.exe x h:\\myjar.jar . h:\\new"}, null, dir) 会发生什么? - viator

3
完整的exec第一个参数被解释为可执行文件。请使用:
p = rt.exec(new String[] {"winrar.exe", "x", "h:\\myjar.jar", "*.*", "h:\\new" }
            null, 
            dir);

Is winrar.exe on your PATH? - Reimeus
我刚刚安装了WinRAR...我没有为WinRAR设置环境路径。 - Trijit
1
它需要在PATH上,否则您将不得不指定可执行文件的完整路径。 - Reimeus

2

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

尝试

 p=r.exec(new String[] {"winrar", "x", "h:\\myjar.jar", "*.*", "h:\\new"}, null, dir);

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接