Як запустити пакетний файл з моєї програми Java?


107

У своєму додатку Java я хочу запустити пакетний файл, який викликає " scons -Q implicit-deps-changed build\file_load_type export\file_load_type"

Здається, я навіть не можу отримати свій пакетний файл для виконання. Мені немає ідеї.

Ось що я маю на Java:

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

Раніше у мене був файл Scotcript Python, який я хотів запустити, але оскільки це не спрацювало, я вирішив зателефонувати скрипту за допомогою пакетного файлу, але цей метод поки не був успішним.

Відповіді:


172

Пакетні файли не виконуються. Для їх запуску потрібна програма (тобто cmd).

У UNIX файл сценарію має shebang (#!) На початку файлу, щоб вказати програму, яка його виконує. Подвійне клацання в Windows виконує Провідник Windows. CreateProcessнічого про це не знає.

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

Примітка. За допомогою start \"\"команди буде відкрито окреме вікно команд із порожнім заголовком і там буде відображено будь-який вихід із пакетного файлу. Він також повинен працювати лише з `cmd / c build.bat ', і в цьому випадку результат може бути прочитаний з підпроцесу на Java за бажанням.


Для мене це говорить, що Windows не може знайти "build.bat". Тож куди я повинен помістити цей файл? Або як мені дати шлях. Будь-які пропозиції?
nanospeck

1
скажемо, у мене є масив команд, а потім повторити цей масив для виконання всіх команд для (i = 0 до command.length) {Runtime.getRuntime (). exec ("cmd / c start buil.bat"); } тоді для кожної ітерації (для кожної команди) відкривається вікно команд, що очевидно. Як уникнути того, що я маю на увазі виконання всіх команд на одному вікні.
viveksinghggits

1
У нас є якийсь код, який безпосередньо називається "gradlew.bat", не ставлячи перед ним речі "cmd / c", і цей код якось працює. Тому я здогадуюсь, що Java або Windows вирішили проблему в якийсь момент. Якщо ми спробуємо виконати "gradlew", це не вдається, тому явно ".bat" все ще потрібен в кінці.
Трежказ

Win+R(Виконання) може виконувати пакетні файли безпосередньо.
Alex78191

21

Іноді час виконання потоку потоку більше, ніж час очікування потоку JVM, це трапляється, коли процес, який ви викликаєте, потребує певного часу для обробки, використовуйте команду waitFor () наступним чином:

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     

}

Таким чином JVM зупинятиметься до тих пір, поки не буде виконаний процес, до якого ви посилаєтесь, перш ніж він продовжиться зі стеком виконання потоків.


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
Було б корисно прокоментувати цей код і сказати нам, чому і що читає InputStream, і чому я хвилююся. Також код файлу пакетного файлу працює добре, але я не можу його змусити викликати помилку Виняток.
Baruch Atta

2
Це призведе до того, що у моєму коді є таке заплутане ім'я змінної, як "є".
Джон Фішер

14

Запуск пакетних файлів за допомогою Java, якщо ви про це говорите ...

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

Це має робити.


10
На питання вже відповіли робочим рішенням. Вам слід запропонувати лише ті рішення, які ви знаєте, що працюють, і описати, чому ви вважаєте, що ваше рішення може бути кращим.
Smamatti

12

ProcessBuilder - це спосіб Java 5/6 для запуску зовнішніх процесів.


2
Чому ProcessBuilder - це шлях в Java 5/6?
Dan Polites

2
Цікавий вибір для відновлення старої публікації ... ProcessBuilder пропонує більше контролю, зокрема можливість легко перенаправляти stderr на stdout. Я також вважаю, що налаштування є більш інтуїтивно зрозумілим, але це особистий преф
basszero

10

Виконаний файл, який використовується для запуску пакетних скриптів, - це те, cmd.exeщо використовується /cпрапор, щоб вказати ім'я пакетного файлу для запуску:

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

Теоретично ви також можете мати змогу запускати Scons таким чином, хоча я цього не перевіряв:

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

EDIT: Amara, ти кажеш, що це не працює. Перелічена вами помилка - це помилка, яку ви отримаєте під час запуску Java з терміналу Cygwin у вікні Windows; це те, що ти робиш? Проблема в тому, що Windows та Cygwin мають різні шляхи, тому версія Windows для Java не знайде файли, які можна виконати на вашому шляху Cygwin. Я можу пояснити далі, якщо це виявиться вашою проблемою.


Дякую. Це все ще не працює - цей фрагмент коду навіть не виконується в моєму додатку. Я спробую інший варіант, який ти представив. Знову дякую.
Amara

Коли я спробую другу альтернативу, це дає мені цю помилку: Виняток у потоці "main" java.io.IOException: Не вдається запустити програму "scons": помилка CreateProcess = 2, система не може знайти вказаний файл
Amara

Ні, у мене немає терміналу Cygwin. Я використовую термінал Windows Command. Дивно - я не знаю, чому це не вийшло. Це мене зовсім бентежить.
Amara

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

тестовано на jdk1.5 та jdk1.6

Це добре працювало для мене, сподіваюся, це допомагає і іншим. щоб отримати це, я боровся більше днів. :(


1
додати це ==> BufferedReader Reader = новий BufferedReader (новий InputStreamReader (p.getInputStream ())); Рядок рядка = читач.readLine (); while (рядок! = null) {System.out.println (рядок); line = reader.readLine (); }
Сурен

2

У мене було те саме питання. Однак іноді CMD не вдається запустити мої файли. Ось чому я створюю temp.bat на своєму робочому столі, далі цей temp.bat запустить мій файл, а наступний тимчасовий файл буде видалений.

Я знаю, що це більший код, проте він працював для мене на 100%, коли навіть Runtime.getRuntime (). Exec () не вдалося.

// 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

Наступне працює добре:

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

що означає / с означає?
Amal lal TL

0

Цей код виконає дві command.bat, які існують у шляху C: / folders / folder.

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

0

Для розширення на зловмиснику @ Isha ви можете просто виконати наступне, щоб отримати повернутий результат (post-facto не в реальному часі) запущеного сценарію:

try {
    Process process = Runtime.getRuntime().exec("cmd /c start D:\\temp\\a.bat");
    System.out.println(process.getText());
} catch(IOException e) {
    e.printStackTrace();
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.