Внешний процесс, запущенный с помощью ProcessBuilder / Runtime.exec (), не работает в XP, работает в Win 7 - PullRequest
6 голосов
/ 08 февраля 2012

Я работаю над Java-программой, которая должна извлекать серийный номер компьютера, серийный номер процессора и т. Д. В Windows интерфейс WMI является лучшим способом запроса такой информации, а стандартный способ запроса с использованием командной строки -

wmic bios get serialnumber

, который производит вывод:

SerialNumber
WWV46RT609A3467173E

Переводя это на Java, я использовал и Runtime.exec (), и ProcessBuilder, например, так:делал ранее).Здесь компонент и элемент соответствуют 'bios' и 'serialnumber' в командной строке выше.

    String ret = "";
    ProcessBuilder pb = new ProcessBuilder("wmic", component, "get", item);
    pb.redirectErrorStream(true);
    // Process p = Runtime.getRuntime().exec(
    // "wmic " + component + " get " + item);
    Process p = pb.start();
    InputStreamReader isr = new InputStreamReader(p.getInputStream());
    BufferedReader input = new BufferedReader(isr);
    String str;
    while ((str = input.readLine()) != null) {
        if (str.equalsIgnoreCase(item) || StringUtils.isBlank(str)) {
            continue;
        }
        ret = str.trim();
    }
    input.close(); 
    isr.close();
    System.out.println(ret); 

Этот фрагмент прекрасно работает в Windows 7, но зависает в Windows XP.Использование wmic из командной строки работает на обеих ОС.Я прочитал здесь , что существует проблема с обработкой как stdout, так и stderr вызываемого процесса, следовательно, вызов redirectErrorStream ().

Почему он работает безупречно в Windows 7, но не работает в XP?Есть ли другой способ, кроме порождения отдельного потока, то есть ' StreamGobbler '?(Связанный пример довольно древний и предшествует классу ProcessBuilder с его вызовом redirectErrorStream ().

Ответы [ 2 ]

6 голосов
/ 12 июня 2012

Я надеюсь, что вы уже получили решение этой проблемы.Если нет, то это то, что вам нужно сделать.Во-первых, я также столкнулся с теми же проблемами и обнаружил, что это проблема bufferedReader.Это попадает в тупиковую ситуацию, которая приводит к зависанию Windows XP.Решение состоит в том, чтобы смоделировать конец строки (eof) для буферизованного считывателя, добавив "<NUL" команду.

 String[] command = {"CMD", "/C", "WMIC COMPUTERSYSTEM GET USERNAME <NUL "} and executing this command. 
0 голосов
/ 08 февраля 2012

Вы должны использовать потоки для захвата выходов (стандарт и ошибка).

Вы также можете взглянуть на эту библиотеку Apache .

...