2009-03-05 17 views
96

En mi aplicación Java, quiero ejecutar un archivo por lotes que llama "scons -Q implicit-deps-changed build\file_load_type export\file_load_type"¿Cómo ejecuto un archivo por lotes desde mi aplicación Java?

Parece que ni siquiera puedo conseguir mi archivo por lotes para ejecutar. Estoy sin ideas.

Esto es lo que tengo en Java:

Runtime. 
    getRuntime(). 
    exec("build.bat", null, new File(".")); 

Anteriormente, tenía un archivo de Python Sconscript que quería correr, pero ya eso no funcionó decidí que iba a llamar a la secuencia de comandos a través de un archivo por lotes pero ese método no ha tenido éxito hasta el momento.

Respuesta

155

Los archivos de proceso por lotes no son ejecutables. Necesitan una aplicación para ejecutarlos (es decir, cmd).

En UNIX, el archivo de script tiene tinglado (#!) Al comienzo de un archivo para especificar el programa que lo ejecuta. El Explorador de Windows realiza un doble clic en Windows. CreateProcess no sabe nada al respecto.

Runtime. 
    getRuntime(). 
    exec("cmd /c start \"\" build.bat"); 

Nota: Con el comando start \"\", se abrirá una ventana de comandos independiente con un título en blanco y cualquier salida del archivo por lotes se mostrará allí. También debería funcionar con `cmd/c build.bat ', en cuyo caso la salida se puede leer del subproceso en Java si se desea.

+0

Para mí, dice que Windows no puede encontrar "build.bat". Entonces, ¿dónde debería poner este archivo? O cómo debería dar el camino. ¿Alguna sugerencia? – nanospeck

+1

Digamos que tengo una serie de comandos y luego iterar esa matriz para ejecutar todos los comandos for (i = 0 a commands.length) { Runtime.getRuntime(). Exec ("cmd/c comenzar buil.bat") ; } luego, para cada iteración (para cada comando) se abre una ventana de comandos que es obvia. ¿Cómo puedo evitar eso? Me refiero a ejecutar todos los comandos en una ventana. – viveksinghggits

+0

Tenemos un código que llama directamente "gradlew.bat" sin poner cosas "cmd/c" delante de él, y ese código funciona de alguna manera. Así que supongo que Java o Windows arreglaron parte del problema en algún momento. Si tratamos de ejecutar "gradlew", eso falla, así que claramente el ".bat" todavía se necesita al final. – Trejkaz

9

El ejecutable utilizado para ejecutar secuencias de comandos por lotes es cmd.exe que utiliza la bandera /c para especificar el nombre del archivo por lotes para ejecutar:

Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "build.bat"}); 

Teóricamente también debe ser capaz de ejecutar Scons de esta manera, aunque No he probado esto:

Runtime.getRuntime().exec(new String[]{"scons", "-Q", "implicit-deps-changed", "build\file_load_type", "export\file_load_type"}); 

EDITAR: Amara, dices que esto no está funcionando. El error que enumeró es el error que obtendría al ejecutar Java desde un terminal Cygwin en un cuadro de Windows; es esto lo que estás haciendo? El problema con eso es que Windows y Cygwin tienen diferentes rutas, por lo que la versión de Windows de Java no encontrará el ejecutable scons en su ruta Cygwin. Puedo explicar más si este es tu problema.

+0

Gracias. Todavía no funciona, esa pieza de código ni siquiera se ejecuta en mi aplicación. Probaré la otra opción que presentaste. Gracias de nuevo. – Amara

+0

Cuando intento la segunda alternativa me da este error: Excepción en el hilo "principal" java.io.IOException: No se puede ejecutar el programa "scons": CreateProcess error = 2, El sistema no puede encontrar el archivo especificado – Amara

+0

No, yo no tener terminal Cygwin. Yo uso el terminal de comando de Windows. Es extraño, no sé por qué no funcionaría. Me desconcierta por completo. – Amara

11

ProcessBuilder es la forma Java 5/6 de ejecutar procesos externos.

+1

¿Por qué ProcessBuilder es el camino a seguir en Java 5/6? –

+2

Elección interesante para resucitar una publicación anterior ... ProcessBuilder ofrece más control, específicamente la capacidad de redireccionar fácilmente stderr a stdout. También encuentro que la configuración es más intuitiva, pero es una preferencia personal. – basszero

18
Runtime runtime = Runtime.getRuntime(); 
try { 
    Process p1 = runtime.exec("cmd /c start D:\\temp\\a.bat"); 
    InputStream is = p1.getInputStream(); 
    int i = 0; 
    while((i = is.read()) != -1) { 
     System.out.print((char)i); 
    } 
} catch(IOException ioException) { 
    System.out.println(ioException.getMessage()); 
} 
+0

Sería útil comentar este código y decirnos por qué y qué está leyendo InputStream, y por qué me importa. Además, el código del archivo de proceso por lotes se está ejecutando muy bien, pero no consigo que genere un error de excepción. –

+0

Me volvería loco tener un nombre de variable tan confuso como "es" en mi código. –

20

a veces el tiempo del proceso de ejecución del hilo de rosca es mayor que el tiempo de espera JVM proceso, que solía suceder cuando el proceso está invocando necesita algún tiempo para ser procesados, utilice el comando waitFor() de la siguiente manera:

try{  
    Process p = Runtime.getRuntime().exec("file location here, don't forget using/instead of \\ to make it interoperable"); 
    p.waitFor(); 

}catch(IOException ex){ 
    //Validate the case the file can't be accesed (not enought permissions) 

}catch(InterruptedException ex){ 
    //Validate the case the process is being stopped by some external situation  

} 

De esta manera, la JVM se detendrá hasta que el proceso Lo que está invocando se hace antes de continuar con la pila de ejecución de subprocesos.

13

Para ejecutar archivos por lotes utilizando Java si eso es que estamos hablando ...

String path="cmd /c start d:\\sample\\sample.bat"; 
Runtime rn=Runtime.getRuntime(); 
Process pr=rn.exec(path);` 

Esto debe hacerlo.

+8

La pregunta ya fue respondida con una solución de trabajo. Debe ofrecer solo soluciones que sepa que están funcionando y describir por qué cree que su solución podría ser mejor. – Smamatti

3
Process p = Runtime.getRuntime().exec( 
    new String[]{"cmd", "/C", "orgreg.bat"}, 
    null, 
    new File("D://TEST//home//libs//")); 

probado con jdk1.5 y jdk1.6

Esto funcionó bien para mí, espero que ayude a otros también. para obtener esto, he tenido problemas más días. :(

+1

add this ==> BufferedReader reader = new BufferedReader (new InputStreamReader (p.getInputStream())); \t \t \t String line = reader.readLine(); \t \t \t \t \t \t \t tiempo (línea! = Null) { \t \t \t \t System.out.println (línea); \t \t \t \t line = reader.readLine(); \t \t \t} – Suren

0

La siguiente está trabajando muy bien:

String path="cmd /c start d:\\sample\\sample.bat"; 
Runtime rn=Runtime.getRuntime(); 
Process pr=rn.exec(path); 
2

que tenían el mismo problema CMD Sin embargo a veces no puede ejecutar los archivos de mi Es por eso que creo un temp.bat en mi escritorio, al lado de esta temperatura.. .bat va a ejecutar mi archivo, y luego se eliminará el archivo temporal.

Sé que es un código más grande, pero funcionó para mí en un 100% incluso cuando Runtime.getRuntime() .exec() Falló

// creating a string for the Userprofile (either C:\Admin or whatever) 
String userprofile = System.getenv("USERPROFILE"); 

BufferedWriter writer = null; 
     try { 
      //create a temporary file 
      File logFile = new File(userprofile+"\\Desktop\\temp.bat"); 
      writer = new BufferedWriter(new FileWriter(logFile)); 

      // Here comes the lines for the batch file! 
      // First line is @echo off 
      // Next line is the directory of our file 
      // Then we open our file in that directory and exit the cmd 
      // To seperate each line, please use \r\n 
      writer.write("cd %ProgramFiles(x86)%\\SOME_FOLDER \r\nstart xyz.bat \r\nexit"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       // Close the writer regardless of what happens... 
       writer.close(); 
      } catch (Exception e) { 
      } 

     } 

     // running our temp.bat file 
     Runtime rt = Runtime.getRuntime(); 
     try { 

      Process pr = rt.exec("cmd /c start \"\" \""+userprofile+"\\Desktop\\temp.bat"); 
      pr.getOutputStream().close(); 
     } catch (IOException ex) { 
      Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); 

     } 
     // deleting our temp file 
     File databl = new File(userprofile+"\\Desktop\\temp.bat"); 
     databl.delete(); 
0

Este código ejecutará dos comandos.bat que existen en la ruta C: carpeta/carpetas.

Runtime.getRuntime().exec("cd C:/folders/folder & call commands.bat"); 
Cuestiones relacionadas