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?
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
Vous pouvez essayer ceci: -
Process p = Runtime.getRuntime().exec(command);
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
).
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);
}
}
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");
Voici une implémentation plus complète de l'exécution en ligne de commande.
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
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);
}
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.
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");
Essaye ça:
Process runtime = Runtime.getRuntime().exec("cmd /c start notepad++.exe");