2010-12-15 66 views
5

que je dois exécuter à partir de Java un script batch, qui ne suitJava: Détection rapide de l'utilisateur lors de l'exécution d'un script batch de Java

1) Une fois démarré, il effectue un long (jusqu'à plusieurs secondes) tâche.

2) Ensuite, il affiche une invite "Mot de passe:".

3) Ensuite, l'utilisateur tape le mot de passe et appuie sur la touche Entrée.

4) Ensuite, le script termine son travail. Je sais comment lancer le script à partir de Java, je sais lire la sortie du script batch en Java, mais je ne sais pas comment attendre que l'invite du mot de passe apparaisse (comment je sais que le le script batch attend l'entrée du mot de passe). Donc, ma question est: Comment savoir quand le script batch a imprimé l'invite?

Actuellement, je code suivant:

final Runtime runtime = Runtime.getRuntime(); 
final String command = ... ; 

final Process proc = runtime.exec(command, null, this.parentDirectory); 

final BufferedReader input = new BufferedReader(new InputStreamReader(
    proc.getInputStream())); 

String line = null; 

while ((line = input.readLine()) != null) { 
LOGGER.debug("proc: " + line); 
} 

Répondre

3

Cela devrait faire le travail:

public static void main(final String... args) throws IOException, InterruptedException { 
    final Runtime runtime = Runtime.getRuntime(); 
    final String command = "..."; // cmd.exe 

    final Process proc = runtime.exec(command, null, new File(".")); 

    final BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream())); 

    StringBuilder sb = new StringBuilder(); 
    char[] cbuf = new char[100]; 
    while (input.read(cbuf) != -1) { 
     sb.append(cbuf); 
     if (sb.toString().contains("Password:")) { 
      break; 
     } 
     Thread.sleep(1000); 
    } 
    System.out.println(sb); 
} 
+0

Etes-vous sûr qu'il est getOutputStream()? Pour le moment, je peux voir une partie de la sortie du script batch en utilisant input.readLine() (voir l'instruction de journalisation dans mon fragment de code). Mais pas tout - je ne peux pas détecter l'invite de cette façon. –

+0

ma première réponse était un non-sens. Le javadoc explique le flux de sortie et d'entrée: http://download.oracle.com/javase/6/docs/api/java/lang/Process.html. – remipod

+0

Merci pour votre code. Malheureusement, l'invite de mot de passe n'est pas terminée par un saut de ligne. C'est pourquoi readline ne fonctionne pas dans ce cas. –

1

Celui-ci semble fonctionner:

@Override 
public void run() throws IOException, InterruptedException { 
    final Runtime runtime = Runtime.getRuntime(); 
    final String command = ...; 

    final Process proc = runtime.exec(command, null, this.parentDirectory); 

    final BufferedReader input = new BufferedReader(new InputStreamReader(
      proc.getInputStream())); 

    String batchFileOutput = ""; 

    while (input.ready()) { 
     char character = (char) input.read(); 
     batchFileOutput = batchFileOutput + character; 
    } 

    // Batch script has printed the banner 
    // Wait for the password prompt 
    while (!input.ready()) { 
     Thread.sleep(1000); 
    } 

    // The password prompt isn't terminated by a newline - that's why we can't use readLine. 
    // Instead, we need to read the stuff character by character. 
    batchFileOutput = ""; 

    while (input.ready() && (!batchFileOutput.endsWith("Password: "))) { 
     char character = (char) input.read(); 
     batchFileOutput = batchFileOutput + character; 
    } 

    // When we are here, the prompt has been printed 
    // It's time to enter the password 

    if (batchFileOutput.endsWith("Password: ")) { 
     final BufferedWriter writer = new BufferedWriter(
       new OutputStreamWriter(proc.getOutputStream())); 

     writer.write(this.password); 

     // Simulate pressing of the Enter key 
     writer.newLine(); 

     // Flush the stream, otherwise it doesn't work 
     writer.flush(); 
    } 

    // Now print out the output of the batch script AFTER we have provided it with a password 
    String line; 

    while ((line = input.readLine()) != null) { 
     LOGGER.debug("proc: " + line); 
    } 

    // Print out the stuff on stderr, if the batch script has written something into it 
    final BufferedReader error = new BufferedReader(new InputStreamReader(
      proc.getErrorStream())); 

    String errorLine = null; 

    while ((errorLine = error.readLine()) != null) { 
     LOGGER.debug("proc2: " + errorLine); 
    } 

    // Wait until the program has completed 

    final int result = proc.waitFor(); 

    // Log the result 
    LOGGER.debug("result: " + result); 
}