Saya mencoba untuk menjalankan perintah eksternal dari kode java, tetapi ada perbedaan yang saya perhatikan antara Runtime.getRuntime().exec(...)
dan new ProcessBuilder(...).start()
.
Saat menggunakan Runtime
:
Process p = Runtime.getRuntime().exec(installation_path +
uninstall_path +
uninstall_command +
uninstall_arguments);
p.waitFor();
exitValue adalah 0 dan perintah dihentikan dengan ok.
Namun, dengan ProcessBuilder
:
Process p = (new ProcessBuilder(installation_path +
uninstall_path +
uninstall_command,
uninstall_arguments)).start();
p.waitFor();
nilai keluar adalah 1001 dan perintah berakhir di tengah, meskipun waitFor
kembali.
Apa yang harus saya lakukan untuk mengatasi masalah tersebut ProcessBuilder
?
cmd.exe
.Lihatlah bagaimana
Runtime.getRuntime().exec()
melewatkan perintah String keProcessBuilder
. Ia menggunakan tokenizer dan meledakkan perintah menjadi token individu, lalu memanggilexec(String[] cmdarray, ......)
yang menyusun aProcessBuilder
.Jika Anda membuat file
ProcessBuilder
dengan larik string, bukan satu, Anda akan mendapatkan hasil yang sama.The
ProcessBuilder
konstruktor mengambilString...
vararg, sehingga melewati seluruh perintah sebagai String tunggal memiliki efek yang sama seperti memanggil perintah yang dalam tanda kutip di terminal:sumber
Tidak ada perbedaan antara
ProcessBuilder.start()
danRuntime.exec()
karena penerapannyaRuntime.exec()
adalah:Jadi kode:
harus sama dengan:
Terima kasih dave_thompson_085 atas komentarnya
sumber
public Process exec(String command, String[] envp, File dir)
-String
NOTString[]
- yang memanggilStringTokenizer
dan menempatkan token dalam array yang kemudian diteruskan (secara tidak langsung) keProcessBuilder
, yang IS perbedaan seperti yang dinyatakan dengan benar oleh tiga jawaban dari 7 tahun yang lalu.Ya ada bedanya.
The
Runtime.exec(String)
Metode mengambil string perintah tunggal yang terbagi menjadi perintah dan urutan argumen.The
ProcessBuilder
konstruktor mengambil (varargs) array dari string. String pertama adalah nama perintah dan sisanya adalah argumen. (Ada konstruktor alternatif yang mengambil daftar string, tetapi tidak ada yang mengambil satu string yang terdiri dari perintah dan argumen.)Jadi apa yang Anda perintahkan untuk dilakukan ProcessBuilder adalah menjalankan "perintah" yang namanya memiliki spasi dan sampah lain di dalamnya. Tentu saja, sistem operasi tidak dapat menemukan perintah dengan nama tersebut, dan eksekusi perintah gagal.
sumber
Runtime.exec(cmd)
secara efektif merupakan jalan pintas untukRuntime.exec(cmd.split("\\s+"))
. TheProcessBuilder
kelas tidak memiliki konstruktor yang setara langsung keRuntime.exec(cmd)
. Inilah poin yang saya buat dalam jawaban saya.new ProcessBuilder("command arg1 arg2")
, parastart()
panggilan tidak akan melakukan apa yang Anda harapkan. Ini mungkin akan gagal, dan hanya akan berhasil jika Anda memiliki perintah dengan spasi dalam namanya. Inilah masalah yang ditanyakan OP!