本文介绍了JNA Windows服务启动类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我一直在玩JNA,并且能够使用下面的代码返回Windows服务的状态(即启动或停止)。我不知道如何返回服务的启动类型。我确信JNA之外还有其他方法,但如果可能,我想继续使用JNA。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(); }}推荐答案这里的问题是,虽然JNA平台特定代码提供了查询服务状态的处理,但它不支持查询服务的配置。这意味着,为此,您需要为相关函数提供JNA映射。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.在这种情况下,您需要的函数是 QueryServiceConfig(在Advapi32中定义了 。此功能填写 QUERY_SERVICE_CONFIG 结构,其中包含 dwStartType 属性,该属性对应于各种启动类型值。The function you'd want, in this case, is QueryServiceConfig() defined in Advapi32. This function fills in a QUERY_SERVICE_CONFIG structure, which has a dwStartType property which corresponds to the various start-up type values.幸运的是,使用JNA映射本机函数非常简单:您只需声明一个类似的接口(我提供的代码示例是用Groovy编写的;转换为Java应该非常简单):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):interface MyAdvapi32 extends StdCallLibrary { MyAdvapi32 INSTANCE = (Advapi32) Native.loadLibrary("Advapi32", MyAdvapi32.class, W32APIOptions.UNICODE_OPTIONS); boolean QueryServiceConfig( SC_HANDLE hService, QUERY_SERVICE_CONFIG lpServiceConfig, int cbBufSize, IntByReference pcbBytesNeeded )}(我使用 的定义QueryServiceStatusEx() 在JNA源代码中,其参数与 QueryServiceConfig()的参数非常相似。请注意 QueryServiceStatusEx()最终是由 W32Service#queryStatus() )。(I derived this using the definition for QueryServiceStatusEx() in the JNA source, whose parameters closely mirror the parameters for QueryServiceConfig(). Note that QueryServiceStatusEx() is ultimately the function called by W32Service#queryStatus()).但是,我们的功能需要一个 QUERY_SERVICE_CONFIG 结构,它没有在JNA中的任何地方定义。使用JNA的模型 SERVICE_STATUS_PROCESS 定义我们最终得到的结果如下:However, our function requires a QUERY_SERVICE_CONFIG structure, which is not defined anywhere in JNA. Working from the model of the JNA's SERVICE_STATUS_PROCESS definition we end up with something like:class QUERY_SERVICE_CONFIG extends Structure { public DWORD dwServiceType public DWORD dwStartType public DWORD dwErrorControl public char[] lpBinaryPathName public char[] lpLoadOrderGroup public DWORD dwTagId public char[] lpDependencies public char[] lpServiceStartName public char[] lpDisplayName QUERY_SERVICE_CONFIG() {} QUERY_SERVICE_CONFIG(int size) { lpBinaryPathName = new char[256] lpLoadOrderGroup = new char[256] lpDependencies = new char[256] lpServiceStartName = new char[256] lpDisplayName = new char[256] allocateMemory(size) }}(请注意,此结构相当比 SERVICE_STATUS_PROCESS ,因为 SERVICE_STATUS_PROCESS 只有 DWORD 参数。我在第二个构造函数中提供的分配大小,虽然是JNA所需的,但可能不是正确的大小。)(Note that this structure is quite a bit more involved than SERVICE_STATUS_PROCESS, as SERVICE_STATUS_PROCESS only has DWORD parameters. The allocation sizes I provided in the second constructor, while required for JNA, are probably not the right size.)有了我们的结构和新接口,我们可以创建一个调用QueryServiceConfig的方法:Armed with our structure and new interface, we can create a method to call QueryServiceConfig:QUERY_SERVICE_CONFIG queryServiceConfig(W32Service service) { IntByReference size = new IntByReference() MyAdvapi32.INSTANCE.QueryServiceConfig( service.handle, null, 0, size ) QUERY_SERVICE_CONFIG config = new QUERY_SERVICE_CONFIG(size.value) if (!MyAdvapi32.INSTANCE.QueryServiceConfig( service.handle, config, config.size(), size )) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } return config}一次我们已经掌握了所有这些,使用它非常简单:Once we've got all that, using it is pretty simple:QUERY_SERVICE_CONFIG config = queryServiceConfig(service)System.out.println(config.dwStartType) 这篇关于JNA Windows服务启动类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-24 03:02