Java Uygulamamdan bir toplu iş dosyasını nasıl çalıştırırım?


107

Java uygulamamda, " scons -Q implicit-deps-changed build\file_load_type export\file_load_type" çağıran bir toplu iş dosyası çalıştırmak istiyorum

Görünüşe göre toplu iş dosyamı yürütmek için bile alamıyorum. Fikirler tükendi.

Java'da sahip olduğum şey bu:

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

Önceden, çalıştırmak istediğim bir Python Sconscript dosyam vardı, ancak bu işe yaramadığı için betiği bir toplu iş dosyası aracılığıyla çağırmaya karar verdim, ancak bu yöntem henüz başarılı olamadı.

Yanıtlar:


172

Toplu iş dosyaları yürütülebilir değildir. Bunları çalıştırmak için bir uygulamaya ihtiyaçları vardır (yani cmd).

UNIX'te, komut dosyasında, dosyayı çalıştıran programı belirtmek için dosyanın başında shebang (#!) Bulunur. Windows'ta çift tıklama, Windows Gezgini tarafından gerçekleştirilir. CreateProcessbunun hakkında hiçbir şey bilmiyor.

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

Not: Komutla, start \"\"boş bir başlık içeren ayrı bir komut penceresi açılacak ve toplu iş dosyasından herhangi bir çıktı burada görüntülenecektir. Ayrıca sadece "cmd / c build.bat" ile de çalışmalıdır, bu durumda çıktı istenirse Java'daki alt işlemden okunabilir.


Benim için Windows'un "build.bat" dosyasını bulamadığını söylüyor. Peki bu dosyayı nereye koymalıyım? Ya da yolu nasıl vermeliyim? Baska öneri?
nanospeck

1
diyelim ki bir dizi komutum var ve sonra tüm komutları çalıştırmak için bu diziyi yineliyorum (i = 0'dan commands.length'e) {Runtime.getRuntime (). exec ("cmd / c start buil.bat"); } her yineleme için (her komut için) aşikar bir komut penceresi açılır. Tüm komutları tek bir pencerede yürütmeyi kastettiğim nasıl önlenebilir?
viveksinghggits

1
Önüne cmd / c koymadan doğrudan "gradlew.bat" olarak adlandırılan bir kodumuz var ve bu kod bir şekilde çalışıyor. Sanırım ya Java ya da Windows bir noktada sorunun bir kısmını çözdü. "Gradlew" yi çalıştırmayı denersek, bu başarısız olur, bu yüzden açık bir şekilde ".bat" sonuna hala ihtiyaç vardır.
Trejkaz

Win+R(Çalışma Zamanı), toplu iş dosyalarını doğrudan çalıştırabilir.
Alex78191

21

Bazen iş parçacığı yürütme işlem süresi, JVM iş parçacığı bekleme işlem süresinden daha yüksektir, bu, çağırdığınız işlemin işlenmesi biraz zaman aldığında gerçekleşir, waitFor () komutunu aşağıdaki gibi kullanın:

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     

}

Bu şekilde JVM, iş parçacığı yürütme yığınına devam etmeden önce çağırdığınız işlem tamamlanana kadar duracaktır.


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() );
}

2
Bu kodu yorumlamak ve bize InputStream'in neden ve ne okuduğunu ve neden önemsediğimi söylemek faydalı olacaktır. Ayrıca, toplu iş dosyasının kodu iyi çalışıyor, ancak bir hata İstisnası oluşturmasını sağlayamıyorum.
Baruch Atta

2
Kodumda "is" gibi kafa karıştırıcı bir değişken adına sahip olmak beni deli ederdi.
John Fisher

14

Eğer bahsediyorsanız, toplu dosyaları java kullanarak çalıştırmak için ...

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

Bunu yapmalı.


10
Soru zaten çalışan bir çözümle yanıtlandı. Yalnızca işe yaradığını bildiğiniz çözümleri sunmalı ve çözümünüzün neden daha iyi olabileceğini düşündüğünüzü açıklamalısınız.
Smamatti

12

ProcessBuilder , harici işlemleri çalıştırmanın Java 5/6 yoludur.


2
ProcessBuilder neden Java 5 / 6'da gitmenin yoludur?
Dan Polites

2
Eski bir gönderiyi yeniden canlandırmak için ilginç bir seçim ... ProcessBuilder daha fazla kontrol, özellikle de stderr'i stdout'a kolayca yönlendirme yeteneği sunar. Ayrıca kurulumu daha sezgisel buluyorum, ancak bu kişisel bir tercih
basszero

10

Toplu komut dosyalarını çalıştırmak için kullanılan yürütülebilir dosya, çalıştırılacak toplu iş dosyasının adını belirtmek için bayrağı cmd.exekullanan /c:

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

Teorik olarak, bunu test etmemiş olsam da, Scons'u bu şekilde çalıştırabilmelisiniz:

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

DÜZENLEME: Amara, bunun işe yaramadığını söylüyorsun. Listelediğiniz hata, Java'yı bir Windows kutusunda Cygwin terminalinden çalıştırırken alacağınız hatadır; Yaptığın bu mu? Bununla ilgili sorun, Windows ve Cygwin'in farklı yollara sahip olmasıdır, bu nedenle Java'nın Windows sürümü, Cygwin yolunuzda yürütülebilir scons bulamayacaktır. Sorunun bu olduğu ortaya çıkarsa daha fazla açıklayabilirim.


Teşekkür ederim. Hala çalışmıyor - bu kod parçası uygulamamda çalışmıyor bile. Sunduğunuz diğer seçeneği deneyeceğim. Tekrar teşekkürler.
Amara

İkinci alternatifi denediğimde bana şu hatayı veriyor: "main" iş parçacığında istisna java.io.IOException: "scons" programı çalıştırılamıyor: CreateProcess hatası = 2, Sistem belirtilen dosyayı bulamıyor
Amara

Hayır Cygwin terminalim yok. Windows Komut terminalini kullanıyorum. Tuhaf - neden işe yaramadığını bilmiyorum. Beni tamamen şaşırtıyor.
Amara

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

jdk1.5 ve jdk1.6 ile test edildi

Bu benim için iyi çalışıyordu, umarım başkalarına da yardımcı olur. Bunu elde etmek için daha fazla gün uğraştım. :(


1
bunu ekleyin ==> BufferedReader okuyucu = new BufferedReader (yeni InputStreamReader (p.getInputStream ())); Dize satırı = reader.readLine (); while (satır! = boş) {System.out.println (satır); satır = reader.readLine (); }
Suren

2

Ben de aynı sorunu yaşadım. Ancak bazen CMD dosyalarımı çalıştıramadı. Bu yüzden masaüstümde bir temp.bat oluşturuyorum, sonra bu temp.bat dosyamı çalıştıracak ve ardından geçici dosya silinecek.

Bunun daha büyük bir kod olduğunu biliyorum, ancak Runtime.getRuntime (). Exec () bile başarısız olduğunda benim için% 100 çalıştı.

// 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();

1

Aşağıdakiler iyi çalışıyor:

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

/ c ne anlama geliyor?
Amal lal

0

Bu kod, C: / klasörler / klasör yolunda bulunan iki commands.bat dosyasını çalıştıracaktır.

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

0

@ Isha'nın yanıtlayıcısını genişletmek için , çalıştırılan komut dosyasının döndürülen çıktısını (post-facto gerçek zamanlı değil) almak için yalnızca aşağıdakileri yapabilirsiniz:

try {
    Process process = Runtime.getRuntime().exec("cmd /c start D:\\temp\\a.bat");
    System.out.println(process.getText());
} catch(IOException e) {
    e.printStackTrace();
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.