ProcessBuilder не может запустить программу, найденную в PATH

Я пытаюсь пробежать npm через ProcessBuilder.start(). Однако, по крайней мере, в Windows всякий раз, когда я пытаюсь запустить процесс, не указывая полный путь к исполняемому файлу, вызов завершается с ошибкой «CreateProcess = 2».

Обновлено: каталог npm находится в переменной среды PATH.

Образец кода:

public class Main {
    public static void main(String[] args) {
        // Won't work
        invokeCommand(new String[] {"npm", "--version"});

        // Will work
        invokeCommand(new String[] {"C:\\Program Files\\nodejs\\npm.cmd", "--version"});
    }

    private static void invokeCommand(String[] args) {
        System.out.println("INVOKING: " + String.join(" ", args));

        ProcessBuilder pb = new ProcessBuilder(args);

        try {
            Process p = pb.start();
            p.waitFor();

            dumpStdout(p);
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        System.out.println();
    }

    private static void dumpStdout(Process p) throws IOException {
        String line;
        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

        while ((line = reader.readLine()) != null) {
            System.out.println("STDOUT: " + line);
        }

        reader.close();
    }
}

Почему это так? Это потому, что npm — это пакетная команда? Это очень неудобно, если не сказать несовместимо с другими программами, такими как java или node, которые прекрасно работают без полных путей. Спасибо.

ты пробовал "npm.cmd"?

user85421 13.06.2024 23:01

@user85421 user85421 Я бы старался избегать этого, потому что программа будет работать на разных ОС, но это выглядит как незначительный компромисс.

Humberto 17.06.2024 21:08

Я думаю, что "C:\\Program Files\\nodejs\\npm.cmd" так же плохо, если не хуже, с точки зрения зависимости от ОС... просто попросили попробовать, неважно

user85421 17.06.2024 21:44
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
3
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Java сканирует Path на наличие исполняемых файлов, но не ссылается на переменную PATHEXT. Поэтому измените программу запуска, указав расширение исполняемого файла, поэтому оно работает с добавлением «.cmd».

Он будет работать с расширением {"npm.cmd", "--version"} или без расширения, если вы используете терминал, например {"cmd.exe", "/c", yourcommand}, поскольку CMD сканирует расширения файлов в переменной среды PATHEXT. Обычно устанавливается:

 PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

Спасибо. Вероятно, мне придется убедиться, что в Windows добавлено правильное расширение файла; это несколько нежелательно, но это не большая проблема.

Humberto 17.06.2024 21:07

Другие вопросы по теме