简体   繁体   English

使用JNA获取服务列表

[英]Get list of services using JNA

I need to list all of the services installed, running and stopped (STATE = ALL) . 我需要列出所有已安装,正在运行和已停止的服务(STATE = ALL) Earlier I was using command "sc query" but I need to do this using JNA. 之前我使用命令“ sc query”,但我需要使用JNA来执行此操作。 I've never used JNA before so I don't know much. 我以前从未使用过JNA,所以我并不了解。

I found this Query all Windows Services with JNA and did what was told in the answer but I can't get it to work. 我发现此查询使用JNA查询所有Windows服务,并做了回答,但无法正常工作。

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);
    }
}

All I can get from this is error: 我只能从这得到错误:

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)

Your error is in size.setValue(retz.getValue()); 您的错误在于size.setValue(retz.getValue()); . When you call the method a second time, you are using size as the lpResumeHandle field: 当您再次调用该方法时,您将size用作lpResumeHandle字段:

A pointer to a variable that, on input, specifies the starting point of enumeration. 指向变量的指针,该变量在输入时指定枚举的起点。 You must set this value to zero the first time the EnumServicesStatusEx function is called. 您必须在第一次调用EnumServicesStatusEx函数时将此值设置为零。 On output, this value is zero if the function succeeds. 在输出中,如果函数成功,则该值为零。 However, if the function returns zero and the GetLastError function returns ERROR_MORE_DATA, this value indicates the next service entry to be read when the EnumServicesStatusEx function is called to retrieve the additional data. 但是,如果该函数返回零,并且GetLastError函数返回ERROR_MORE_DATA,则此值指示当调用EnumServicesStatusEx函数以检索其他数据时要读取的下一个服务条目。

So in your second call you're telling JNA to start iterating after the last element in the previous list. 因此,在第二次调用中,您要告诉JNA在上一个列表中的最后一个元素之后开始迭代。 Not surprisingly, you're getting an empty array ( retz.getValue() == 0) which Structure.toArray() can't handle. 毫不奇怪,您得到了一个空数组( retz.getValue() == 0), Structure.toArray()无法处理。

You should be calling EnumServicesStatusEx with that parameter set to 0 to start enumeration at the beginning. 您应该在将参数设置为0的情况下调用EnumServicesStatusEx ,以便从头开始进行枚举。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM