I've been playing around with JNA and am able to return the status of a Windows Service (i.e. started or stopped) using the code below. I'm not sure how to return the startup type of the service though. I'm sure there are ways outside of JNA, but I would like to continue to use JNA if possible.
import com.sun.jna.*;
import com.sun.jna.Library.Handler;
import com.sun.jna.platform.win32.*;
import com.sun.jna.platform.win32.Advapi32Util.*;
import com.sun.jna.platform.win32.WinNT.*;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.*;
public class WindowsService {
public static void main(String[] args) {
W32ServiceManager serviceManager = new W32ServiceManager();
serviceManager.open(Winsvc.SC_MANAGER_ALL_ACCESS);
W32Service service = serviceManager.openService("W32Time", Winsvc.SC_MANAGER_ALL_ACCESS);
System.out.println(service.queryStatus().dwCurrentState);
service.close();
}
}
Using JNA 4.2.2:
The problem I was having with this structure was the lpDependencies defined as a doubly null terminated array of strings:
So I solved this issue by customizing the type mapping:
I really only cared for the "FromNativeConverter" (DoubleNullString is just a Type marker that has a String[] field):
For reference the ToNativeConverter should just return a Pointer.class type and if needed, could return a Memory block with the String[] converted to a doubly null terminated array of bytes. For JNA's sake, it just needs to know the "type" and a default "null" value (just so it can initialize the structure).
My method signature then becomes:
The problem here is that while the JNA platform-specific code provides handling for querying a service's status, it does not provide support for querying the service's configuration. That means that to do so, you'll need to provide a JNA mapping for the function in question.
The function you'd want, in this case, is
QueryServiceConfig()
defined in Advapi32. This function fills in aQUERY_SERVICE_CONFIG
structure, which has adwStartType
property which corresponds to the various start-up type values.Fortunately, mapping a native function is really straight-forward with JNA: you just declare an interface like so (The code examples I'm providing are written in Groovy; the transformation to Java should be pretty straight-forward):
(I derived this using the definition for
QueryServiceStatusEx()
in the JNA source, whose parameters closely mirror the parameters forQueryServiceConfig()
. Note thatQueryServiceStatusEx()
is ultimately the function called byW32Service#queryStatus()
).However, our function requires a
QUERY_SERVICE_CONFIG
structure, which is not defined anywhere in JNA. Working from the model of the JNA'sSERVICE_STATUS_PROCESS
definition we end up with something like:(Note that this structure is quite a bit more involved than
SERVICE_STATUS_PROCESS
, asSERVICE_STATUS_PROCESS
only hasDWORD
parameters. The allocation sizes I provided in the second constructor, while required for JNA, are probably not the right size.)Armed with our structure and new interface, we can create a method to call QueryServiceConfig:
Once we've got all that, using it is pretty simple:
Here is the program from the previous answer as a java class. IMPORTANT - needs exactly JNA 3.3.0