Bagaimana cara menjalankan file batch dari Aplikasi Java saya?

107

Dalam aplikasi Java saya, saya ingin menjalankan file batch yang memanggil " scons -Q implicit-deps-changed build\file_load_type export\file_load_type"

Tampaknya saya bahkan tidak bisa menjalankan file batch saya. Saya kehabisan ide.

Inilah yang saya miliki di Jawa:

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

Sebelumnya, saya memiliki file Python Sconscript yang ingin saya jalankan tetapi karena itu tidak berhasil, saya memutuskan untuk memanggil skrip melalui file batch tetapi metode itu belum berhasil.

Amara
sumber

Jawaban:

172

File batch tidak dapat dieksekusi. Mereka membutuhkan aplikasi untuk menjalankannya (mis. Cmd).

Di UNIX, file skrip memiliki shebang (#!) Di awal file untuk menentukan program yang menjalankannya. Klik dua kali di Windows dilakukan oleh Windows Explorer. CreateProcesstidak tahu apa-apa tentang itu.

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

Catatan: Dengan start \"\"perintah tersebut, jendela perintah terpisah akan dibuka dengan judul kosong dan setiap keluaran dari file batch akan ditampilkan di sana. Ini juga harus bekerja hanya dengan `cmd / c build.bat", dalam hal ini output dapat dibaca dari sub-proses di Java jika diinginkan.

Paulo Guedes
sumber
Bagi saya, Windows tidak dapat menemukan "build.bat". Jadi di mana saya harus meletakkan file ini? Atau bagaimana saya harus memberi jalan. Ada saran?
nanospeck
1
katakanlah saya memiliki array perintah dan kemudian iterasi array itu untuk menjalankan semua perintah untuk (i = 0 ke commands.length) {Runtime.getRuntime (). exec ("cmd / c start buil.bat"); } lalu untuk setiap iterasi (untuk setiap perintah) jendela perintah terbuka yang jelas. Bagaimana menghindarinya maksud saya menjalankan semua perintah pada satu jendela.
viveksinghggits
1
Kami memiliki beberapa kode yang secara langsung memanggil "gradlew.bat" tanpa meletakkan hal-hal "cmd / c" di depannya, dan kode tersebut bekerja entah bagaimana. Jadi saya kira baik Java atau Windows memperbaiki sebagian dari masalah di beberapa titik. Jika kita mencoba untuk mengeksekusi "gradlew", itu gagal, jadi jelas ".bat" masih dibutuhkan di akhir.
Trejkaz
Win+R(Runtime) dapat menjalankan file batch secara langsung.
Alex78191
21

Kadang-kadang waktu proses eksekusi thread lebih tinggi dari waktu proses thread JVM menunggu, ini biasanya terjadi ketika proses yang Anda panggil membutuhkan waktu untuk diproses, gunakan perintah waitFor () sebagai berikut:

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     

}

Dengan cara ini JVM akan berhenti sampai proses yang Anda panggil selesai sebelum melanjutkan dengan tumpukan eksekusi utas.

Juan Carlos Alpízar
sumber
20
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() );
}
Isha
sumber
2
Akan berguna untuk memberi komentar pada kode ini dan memberi tahu kami mengapa dan apa yang dibaca InputStream, dan mengapa saya peduli. Juga, kode untuk file batch berjalan dengan baik, tetapi saya tidak bisa membuatnya memunculkan pengecualian kesalahan.
Baruch Atta
2
Ini akan membuat saya gila jika memiliki nama variabel yang membingungkan seperti "ada" dalam kode saya.
John Fisher
14

Untuk menjalankan file batch menggunakan java jika itu yang Anda bicarakan ...

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

Ini harus melakukannya.

Abbia
sumber
10
Pertanyaan itu sudah dijawab dengan solusi yang berfungsi. Anda harus menawarkan hanya solusi yang Anda tahu berhasil dan menjelaskan mengapa menurut Anda solusi Anda mungkin lebih baik.
Smamatti
12

ProcessBuilder adalah cara Java 5/6 untuk menjalankan proses eksternal.

basszero
sumber
2
Mengapa ProcessBuilder bisa digunakan di Java 5/6?
Dan Polites
2
Pilihan menarik untuk menghidupkan kembali posting lama ... ProcessBuilder menawarkan lebih banyak kontrol, khususnya kemampuan untuk dengan mudah mengarahkan stderr ke stdout. Saya juga menemukan penyiapannya lebih intuitif, tapi itu preferensi pribadi
basszero
10

Eksekusi yang digunakan untuk menjalankan skrip batch adalah cmd.exeyang menggunakan /cflag untuk menentukan nama file batch yang akan dijalankan:

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

Secara teoritis Anda juga harus dapat menjalankan Scons dengan cara ini, meskipun saya belum menguji ini:

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

EDIT: Amara, Anda mengatakan bahwa ini tidak berfungsi. Kesalahan yang Anda daftarkan adalah kesalahan yang Anda dapatkan saat menjalankan Java dari terminal Cygwin pada kotak Windows; apakah ini yang kamu lakukan? Masalahnya adalah bahwa Windows dan Cygwin memiliki jalur yang berbeda, sehingga versi Windows Java tidak akan menemukan scons yang dapat dieksekusi di jalur Cygwin Anda. Saya bisa menjelaskan lebih lanjut jika ini ternyata menjadi masalah Anda.

Eli Courtwright
sumber
Terima kasih. Itu masih tidak berfungsi - potongan kode itu bahkan tidak dijalankan di aplikasi saya. Saya akan mencoba opsi lain yang Anda berikan. Terima kasih lagi.
Amara
Ketika saya mencoba alternatif kedua, itu memberi saya kesalahan ini: Pengecualian di utas "utama" java.io.IOException: Tidak dapat menjalankan program "scons": CreateProcess error = 2, Sistem tidak dapat menemukan file yang ditentukan
Amara
Tidak, saya tidak memiliki terminal Cygwin. Saya menggunakan terminal Perintah Windows. Aneh - saya tidak tahu mengapa itu tidak berhasil. Itu benar-benar membuatku bingung.
Amara
3
Process p = Runtime.getRuntime().exec( 
  new String[]{"cmd", "/C", "orgreg.bat"},
  null, 
  new File("D://TEST//home//libs//"));

diuji dengan jdk1.5 dan jdk1.6

Ini berfungsi dengan baik untuk saya, semoga membantu orang lain juga. untuk mendapatkan ini saya telah berjuang lebih banyak hari. :(

Suren
sumber
1
tambahkan ini ==> BufferedReader reader = new BufferedReader (new InputStreamReader (p.getInputStream ())); Baris string = reader.readLine (); while (line! = null) {System.out.println (line); line = reader.readLine (); }
Suren
2

Saya memiliki masalah yang sama. Namun terkadang CMD gagal menjalankan file saya. Itu sebabnya saya membuat temp.bat di desktop saya, selanjutnya temp.bat ini akan menjalankan file saya, dan selanjutnya file temp akan dihapus.

Saya tahu ini adalah kode yang lebih besar, namun berhasil untuk saya 100% bahkan ketika Runtime.getRuntime (). Exec () gagal.

// 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();
Ben Jost
sumber
1

Berikut ini berfungsi dengan baik:

String path="cmd /c start d:\\sample\\sample.bat";
Runtime rn=Runtime.getRuntime();
Process pr=rn.exec(path);
bharath
sumber
apa yang dimaksud dengan / c?
Amal lal TL
0

Kode ini akan mengeksekusi dua commands.bat yang ada di jalur C: / folder / folder.

Runtime.getRuntime().exec("cd C:/folders/folder & call commands.bat");
رامي عبد الله
sumber
0

Untuk memperluas anwser @ Isha Anda cukup melakukan hal berikut untuk mendapatkan keluaran yang dikembalikan (post-facto tidak dalam waktu nyata) dari skrip yang dijalankan:

try {
    Process process = Runtime.getRuntime().exec("cmd /c start D:\\temp\\a.bat");
    System.out.println(process.getText());
} catch(IOException e) {
    e.printStackTrace();
}
NoodleOfDeath
sumber