Получить список услуг с использованием JNA - PullRequest
0 голосов
/ 26 февраля 2019

Мне нужно перечислить все установленные, запущенные и остановленные службы (STATE = ALL).Ранее я использовал команду "sc query", но мне нужно сделать это с помощью JNA.Я никогда не использовал JNA раньше, поэтому я не знаю много.

Я нашел это Запрос всех служб Windows с JNA и сделал то, что было сказано в ответе, но я не могу получитьэто работает.

public void getService(){
    IntByReference size = new IntByReference();
    IntByReference lppcbBytesneeded = new IntByReference();
    IntByReference retz = new IntByReference();
    lppcbBytesneeded.setValue(0);
    Winsvc.SC_HANDLE scm = Advapi32.INSTANCE.OpenSCManager(null, null, Winsvc.SC_MANAGER_ENUMERATE_SERVICE);
    boolean ret = CustomAdvapi32.INSTANCE.EnumServicesStatusEx(scm.getPointer(), 0, 0x00000030, 0x0000003, null, 0, lppcbBytesneeded,
            retz, size, null);
    int error = Native.getLastError();

    Memory buf = new Memory(lppcbBytesneeded.getValue());
    size.setValue(retz.getValue());
    ret = CustomAdvapi32.INSTANCE.EnumServicesStatusEx(scm.getPointer(), 0, 0x00000030, 0x0000000,
            buf, lppcbBytesneeded.getValue(), lppcbBytesneeded, retz, size, null);
    error = Native.getLastError();


    ENUM_SERVICE_STATUS_PROCESS serviceInfo = new ENUM_SERVICE_STATUS_PROCESS(buf);
    Structure[] serviceInfos = serviceInfo.toArray(retz.getValue());

    for(int i = 0; i < retz.getValue(); i++) {
        serviceInfo = (ENUM_SERVICE_STATUS_PROCESS) serviceInfos[i];
        System.out.println(serviceInfo.lpDisplayName + " / " + serviceInfo.lpServiceName);
    }
}

Все, что я могу получить от этого, это ошибка:

java.lang.ArrayIndexOutOfBoundsException: 0
at com.sun.jna.Structure.toArray(Structure.java:1562)
at com.sun.jna.Structure.toArray(Structure.java:1587)
at Main.getService(Main.java:156)
at Main.main(Main.java:22)

1 Ответ

0 голосов
/ 26 февраля 2019

Ваша ошибка в size.setValue(retz.getValue());.Когда вы вызываете метод во второй раз, вы используете size в качестве поля lpResumeHandle:

Указатель на переменную, которая при вводе указывает начальную точку перечисления.Вы должны установить это значение равным нулю при первом вызове функции EnumServicesStatusEx.На выходе это значение равно нулю, если функция завершается успешно.Однако, если функция возвращает ноль, а функция GetLastError возвращает ERROR_MORE_DATA, это значение указывает на следующую запись службы, которая будет прочитана при вызове функции EnumServicesStatusEx для получения дополнительных данных.

Итак, во втором вызовевы говорите JNA начать итерацию после последнего элемента в предыдущем списке.Неудивительно, что вы получаете пустой массив (retz.getValue() == 0), который Structure.toArray() не может обработать.

Вы должны вызывать EnumServicesStatusEx с этим параметром, установленным в 0, чтобы начать перечисление сначало.

...