我需要列出所有安装,运行和停止(STATE = ALL)
的服务。之前我使用的是命令“sc query”,但我需要使用JNA执行此操作。我之前从未使用过JNA,所以我不太了解。
我发现这个Query all Windows Services with 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)
你的错误是在size.setValue(retz.getValue());
。当您第二次调用该方法时,您使用size
作为lpResumeHandle
字段:
指向变量的指针,该变量在输入时指定枚举的起始点。首次调用EnumServicesStatusEx函数时,必须将此值设置为零。输出时,如果函数成功,则该值为零。但是,如果函数返回零并且GetLastError函数返回ERROR_MORE_DATA,则此值指示在调用EnumServicesStatusEx函数以检索其他数据时要读取的下一个服务条目。
所以在你的第二次调用中,你告诉JNA开始迭代上一个列表中的最后一个元素。毫不奇怪,你得到一个retz.getValue()
无法处理的空数组(Structure.toArray()
== 0)。
你应该调用EnumServicesStatusEx
并将该参数设置为0以在开头开始枚举。