web-dev-qa-db-fra.com

CreateProcess error = 2, le système ne trouve pas le fichier spécifié

J'écris un programme dans Java qui exécuterait winrar et décompresser un fichier jar pour moi placé dans h:\myjar.jar dans le dossier h:\new. Mon Java va un peu comme ceci

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();
        }
    }
}

Quand j'exécute ceci, j'obtiens cette erreur

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

Quelqu'un peut-il me dire pourquoi je rencontre un tel problème? Quel changement dois-je intégrer au code pour que cela fonctionne?

23
Trijit

En admettant que winrar.exe est dans le PATH, puis Runtime.exec est capable de le trouver. Si ce n’est pas le cas, vous devrez lui fournir le chemin complet, par exemple, en supposant que winrar.exe est installé dans C:/Program Files/WinRAR vous devez utiliser quelque chose comme ...

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

Personnellement, je vous recommanderais d'utiliser ProcessBuilder car il offre, entre autres, quelques possibilités de configuration supplémentaires. Dans la mesure du possible, vous devez également séparer votre commande et vos paramètres en deux éléments String distincts, qui gèrent beaucoup mieux les espaces, par exemple, qu'une seule variable String, par exemple ...

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();

N'oubliez pas de lire le contenu de InputStream à partir du processus, faute de quoi le processus pourrait être bloqué.

37
MadProgrammer

J'ai utilisé ProcessBuilder, mais j'ai eu le même problème. Le problème était d'utiliser la commande comme une seule chaîne (comme si je la taperais dans cmd) au lieu d'un tableau. Par exemple d'en haut. Si je courais

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();

J'ai une erreur. Mais si je courais

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();

tout était bien.

12
EagleEye1984

Le dir que vous avez spécifié est un répertoire de travail du processus en cours d'exécution - la recherche d'un fichier exécutable n'aide pas. Utilisation cmd /c winrar ... pour exécuter le processus à la recherche d'un exécutable dans CHEMIN ou essayez d'utiliser absolute chemin d'accès à winrar .

9
viator

Ma recommandation est de garder la getRuntime().exec parce que exec utilise le ProcessBuilder.

Essayer

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

Le premier argument complet de exec est interprété comme l'exécutable. Utilisation

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