Проблемы при выполнении команды из Java

#java #user-interface #process #action #exec

#java #пользовательский интерфейс #процесс #Экшен #exec

Вопрос:

Я создал этот метод actionPerformed таким образом, что он считывает строку, которую я передаю кнопке (мне нужно было создать свой собственный класс button для хранения этой новой строки), и в зависимости от того, что он говорит, он выполняет другое действие. Одна из возможностей строки — быть чем-то вроде: shell(«»). Предполагается, что это запускает системную команду (командная строка в Windows, команда оболочки в unix / Linux) в фоновом режиме. Это источник метода:

 public void actionPerformed(ActionEvent e) {
        if (e.getSource() == this.button) {
            if (password != "") {

            }
            if (action.startsWith("shell("")) {
                String tmpSHELL = action.substring(7, action.length() - 2);

                try {
                    Process p = Runtime.getRuntime().exec(tmpSHELL);
                } catch (IOException e1) {
                    ErrorDialog error = new ErrorDialog("Error handling your shell action");
                    System.exit(0);
                }

            }
            else if (action.startsWith("frame("")) {
                String tmpFRAME = action.substring(7, action.length() - 2);
                MenuFrame target = ConfigReader.getFrame(tmpFRAME);
                this.parent.setVisible(false);
                this.parent.validate();
                target.setVisible(true);
                target.validate();
            }
            else if (action.equals("exit()")) {
                System.exit(0);
            }
            else {
                ErrorDialog error = new ErrorDialog("You config file contains an invalid action command. Use either shell(), frame() or exit()");
                System.exit(0);
            }   
        }
    }
  

Я знаю, что я получаю доступ к методу, но я не уверен, что команда выполняется успешно. В настоящее время я нахожусь в среде Windows, поэтому я создал простой пакетный скрипт, который отображает некоторый текст, затем ожидает нажатия клавиши перед печатью дерева диска C:. Я поместил .bat в свой рабочий каталог Java и передал строку shell («test») (test — это имя командного файла). Однако, когда я нажимаю кнопку, я получаю диалоговое окно с ошибкой (то, которое я закодировал выше).

Что-то не так с моим кодом или, может быть, с моим пониманием того, как работает выполнение команды оболочки в Java? Команда выдает исключение ввода-вывода, но я, похоже, не могу понять, почему. Заранее спасибо за вашу помощь.

Отслеживание стека:

 java.io.IOException: Cannot run program "test": CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessBuilder.start(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at Button.actionPerformed(Button.java:52)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(Unknown Source)
    at java.lang.ProcessImpl.start(Unknown Source)
    ... 30 more
  

Комментарии:

1. Что именно является значением tmpSHELL ?

2. Это может быть связано с тем, как Windows запускает оболочку для запуска скрипта. В Unix / Linux вы указываете путь к оболочке вверху: she-bang. Немного другой тест (или знание большего количества Windows) помогло бы: попробуйте простую программу.

3. Я полагаю, вам понадобится cmd в Windows, а не shell. Можете ли вы куда-нибудь войти или отобразить в диалоговом окне сообщение об исключении e1 и, при необходимости, трассировку стека?

4. Что-нибудь изменится, если вы скажете shell("test.bat") в вашем реальном примере? Альтернатива: поместите test.bat в каталог, который указан в PATH переменной.

5. Попробуйте добавить каталог, содержащий test, в свой PATH и перезапустить IDE.

Ответ №1:

 The system cannot find the file specified
  

Ваш путь к файлу неверен. Попробуйте передать абсолютный путь к файлу.

 shell("C:/somedirectory/test.bat")
  

Кроме того, вы можете проверить это, полностью удалив тест string. Жестко запрограммируйте выполнение пакетного файла во время выполнения, сделав оператор if всегда истинным и передав путь к вашему пакетному файлу в Runtime.getRuntime().exec()

          if (password != "") {

         }
        if (true) {
            String tmpSHELL = action.substring(7, action.length() - 2);

            try {
                Process p = Runtime.getRuntime().exec("test");
            } catch (IOException e1) {
                ErrorDialog error = new ErrorDialog("Error handling your shell action");
                System.exit(0);
            }

        }
  

Это должно привести к той же ошибке. Затем замените путь к файлу на абсолютный путь к файлу, и вы сможете выполнить командный файл.

 Process p = Runtime.getRuntime().exec("C:/somedirectory/test.bat");
  

Комментарии:

1. Хороший ответ, и да, в конечном итоге это был путь. Причина, по которой я не мог заставить ее работать, когда я пытался ввести полный путь, заключалась в том, что я не избегал обратных косых черт (\ вместо). Спасибо всем за помощь.

Ответ №2:

В Windows попробуйте командную строку:

 "cmd test /c"
  

Ответ №3:

Это потому, что команда test не найдена в переменной окружения system PATH.

Если вы перейдете в командную строку и введете test , произойдет сбой. Это то, на что указывает исключение.