web-dev-qa-db-fra.com

Exécuter des commandes cmd via Java

J'ai trouvé plusieurs extraits de code permettant d'exécuter des commandes cmd via une classe Java, mais je n'ai pas pu le comprendre.

C'est le code pour ouvrir le cmd 

public void excCommand(String new_dir){
    Runtime rt = Runtime.getRuntime();
    try {
        rt.exec(new String[]{"cmd.exe","/c","start"});

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

Et j'ai trouvé d'autres liens pour ajouter d'autres commandes telles que cd http://www.coderanch.com/t/109753/Linux-UNIX/exec-command-cd-command-Java

Comment ouvrir l'invite de commande et insérer des commandes en utilisant Java?

Quelqu'un peut-il m'aider à comprendre comment cd un répertoire tel que:

 cd C:\Program Files\Flowella

puis exécuter d'autres commandes sur ce répertoire?

42
Reham

Une façon d'exécuter un processus d'un répertoire différent au répertoire de travail de votre programme Java consiste à changer de répertoire, puis à exécuter le processus dans la même ligne de commande. Vous pouvez le faire en obtenant cmd.exe pour exécuter une ligne de commande telle que cd some_directory && some_program.

L'exemple suivant change de répertoire et exécute dir à partir de là. Certes, je pourrais juste dir ce répertoire sans avoir besoin de cd, mais ce n’est qu’un exemple:

import Java.io.*;

public class CmdTest {
    public static void main(String[] args) throws Exception {
        ProcessBuilder builder = new ProcessBuilder(
            "cmd.exe", "/c", "cd \"C:\\Program Files\\Microsoft SQL Server\" && dir");
        builder.redirectErrorStream(true);
        Process p = builder.start();
        BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        while (true) {
            line = r.readLine();
            if (line == null) { break; }
            System.out.println(line);
        }
    }
}

Notez aussi que j'utilise une ProcessBuilder pour exécuter la commande. Cela me permet notamment de rediriger l'erreur standard du processus vers sa sortie standard en appelant redirectErrorStream(true). Cela me donne un seul flux à lire.

Cela me donne la sortie suivante sur ma machine:

C:\Users\Luke\StackOverflow>Java CmdTest
 Volume in drive C is Windows7
 Volume Serial Number is D8F0-C934

 Directory of C:\Program Files\Microsoft SQL Server

29/07/2011  11:03    <DIR>          .
29/07/2011  11:03    <DIR>          ..
21/01/2011  20:37    <DIR>          100
21/01/2011  20:35    <DIR>          80
21/01/2011  20:35    <DIR>          90
21/01/2011  20:39    <DIR>          MSSQL10_50.SQLEXPRESS
               0 File(s)              0 bytes
               6 Dir(s)  209,496,424,448 bytes free
115
Luke Woodward

Vous pouvez essayer ceci: -

Process p = Runtime.getRuntime().exec(command);
8
Rahul Tripathi

Si vous souhaitez effectuer des actions comme cd, utilisez:

String[] command = {command_to_be_executed, arg1, arg2};
ProcessBuilder builder = new ProcessBuilder(command);
builder = builder.directory(new File("directory_location"));

Exemple:

String[] command = {"ls", "-al"};
ProcessBuilder builder = new ProcessBuilder(command);
builder = builder.directory(new File("/ngs/app/abc"));
Process p = builder.start();

Il est important de fractionner la commande et tous les arguments dans des chaînes distinctes du tableau de chaînes (sinon, ils ne seront pas fournis correctement par l'API ProcessBuilder).

5
Ashwini Sinha

Mon exemple (de projet réel)

dossier - Fichier.

zipFile, filesString - String;

        final String command = "/bin/tar -xvf " + zipFile + " " + filesString;
        logger.info("Start unzipping: {}    into the folder {}", command, folder.getPath());
        final Runtime r = Runtime.getRuntime();
        final Process p = r.exec(command, null, folder);
        final int returnCode = p.waitFor();

        if (logger.isWarnEnabled()) {
            final BufferedReader is = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            while ((line = is.readLine()) != null) {
                logger.warn(line);
            }
            final BufferedReader is2 = new BufferedReader(new InputStreamReader(p.getErrorStream()));
            while ((line = is2.readLine()) != null) {
                logger.warn(line);
            }
        }
3
iMysak

Le moyen le plus simple serait d’utiliser Runtime.getRuntime.exec() .

Par exemple, pour obtenir une valeur de registre pour le navigateur par défaut sous Windows:

String command = "REG QUERY HKEY_CLASSES_ROOT\\http\\Shell\\open\\command";
try
{
    Process process = Runtime.getRuntime().exec(command);
} catch (IOException e)
{
    e.printStackTrace();
}

Utilisez ensuite une Scanner pour obtenir le résultat de la commande, si nécessaire.

Scanner kb = new Scanner(process.getInputStream());

Note: le \ est un caractère d'échappement dans une String et doit être échappé pour fonctionner correctement (d'où le \\).


Cependant, il n'y a pas d'exécutable appelé cd, car il ne peut pas être implémenté dans un processus séparé.

Le seul cas où le répertoire de travail en cours est important est l'exécution d'un processus externe (en utilisant ProcessBuilder ou Runtime.exec() ). Dans ces cas, vous pouvez spécifier explicitement le répertoire de travail à utiliser pour le processus nouvellement démarré.

Manière la plus simple pour votre commande: 

System.setProperty("user.dir", "C:\\Program Files\\Flowella");
2
syb0rg

Voici une implémentation plus complète de l'exécution en ligne de commande.

Usage

executeCommand("ls");

Sortie:

12/27/2017 11:18:11:732: ls
12/27/2017 11:18:11:820: build.gradle
12/27/2017 11:18:11:820: gradle
12/27/2017 11:18:11:820: gradlew
12/27/2017 11:18:11:820: gradlew.bat
12/27/2017 11:18:11:820: out
12/27/2017 11:18:11:820: settings.gradle
12/27/2017 11:18:11:820: src

Code

private void executeCommand(String command) {
    try {
        log(command);
        Process process = Runtime.getRuntime().exec(command);
        logOutput(process.getInputStream(), "");
        logOutput(process.getErrorStream(), "Error: ");
        process.waitFor();
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
    }
}

private void logOutput(InputStream inputStream, String prefix) {
    new Thread(() -> {
        Scanner scanner = new Scanner(inputStream, "UTF-8");
        while (scanner.hasNextLine()) {
            synchronized (this) {
                log(prefix + scanner.nextLine());
            }
        }
        scanner.close();
    }).start();
}

private static SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss:SSS");

private synchronized void log(String message) {
    System.out.println(format.format(new Date()) + ": " + message);
}
2
Ilya Gazman

Une fois que vous avez obtenu la référence à Process, vous pouvez appeler getOutpuStream dessus pour obtenir l'entrée standard de l'invite cmd. Ensuite, vous pouvez envoyer n’importe quelle commande sur le flux en utilisant la méthode write comme avec n’importe quel autre flux.

Notez que c'est process.getOutputStream () qui est connecté au stdin sur le processus engendré. De même, pour obtenir le résultat d'une commande, vous devez appeler getInputStream, puis le lire comme n'importe quel autre flux d'entrée.

1
Akhilesh Singh

Vous ne pouvez pas exécuter cd de cette façon, car cd n'est pas un vrai programme; c'est une partie intégrée de la ligne de commande, qui ne fait que modifier l'environnement de la ligne de commande. Cela n'a aucun sens de l'exécuter dans un sous-processus, car vous modifiez alors l'environnement de ce sous-processus - mais ce sous-processus se ferme immédiatement, ce qui permet de supprimer son environnement.

Pour définir le répertoire de travail actuel dans votre programme Java actuel, vous devez écrire:

System.setProperty("user.dir", "C:\\Program Files\\Flowella");
1
ruakh

Essaye ça: 

Process runtime = Runtime.getRuntime().exec("cmd /c start notepad++.exe");
1
Miguel Vieira

Le moyen le plus simple et le plus court consiste à utiliser CmdTool library.

new Cmd()
         .configuring(new WorkDir("C:/Program Files/Flowella"))
         .command("cmd.exe", "/c", "start")
         .execute();

Vous pouvez trouver plus d'exemples ici .

0
Aleksei Sotnikov