有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java CreateProcess error=2,系统找不到指定的文件

我正在用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) 个答案

  1. # 1 楼答案

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

  2. # 2 楼答案

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

    p = rt.exec(new String[] {"winrar.exe", "x", "h:\\myjar.jar", "*.*", "h:\\new" }
                null, 
                dir);
    
  3. # 3 楼答案

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

  4. # 4 楼答案

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

    一切都很好

  5. # 5 楼答案

    假设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的内容,否则可能会导致进程暂停

  6. # 6 楼答案

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

    试一试

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