TL; DR :我有一个用Java编写的Windows服务,它受震动并与Procrun一起安装。我从W32Service.startService()
开始。该服务何时通知Windows已启动?
我正在使用用Java编写的Windows服务。我一直在使用Procrun进行安装,并使用JNA与它们一起使用(特别是com.sun.jna.platform.win32.W32Service)。
我想了解W32Service
对象的waitForNonPendingState()
方法的 exact 行为(它是Y的X:理解 exact startService()
的行为)。
waitForNonPendingState()
实际上非常简单:它轮询服务的状态,直到它处于非挂起状态或发生超时。但是,如何将服务转换为非挂起状态并不是那么简单。
微软的Service State Transitions page说:
服务的初始状态为SERVICE_STOPPED。当SCM启动服务时,它将服务状态设置为SERVICE_START_PENDING并调用服务的ServiceMain函数。然后,该服务使用Service ServiceMain Function中描述的技术之一完成其初始化。服务完成初始化并准备开始接收控制请求后,服务将调用SetServiceStatus来报告SERVICE_RUNNING ...
但是,这并不能真正说明该服务如何做到这一点。 ServiceMain注释也只是说“ 服务控制管理器(SCM)等待,直到服务报告SERVICE_RUNNING状态。”;据我所知,这非常具体。
这带给我一个问题: java Windows服务如何“知道”它已完成初始化?
换句话说,如果我使用main()
方法安装了服务:
public class SampleService {
public static void main(String[] args) {
if ("start".equals(args[0]))
new SampleService();
}
public SampleService() {
// do a whole bunch of stuff
}
}
然后我打电话给
W32Service service = serviceManager.openService("SampleService",
Winsvc.SC_MANAGER_ALL_ACCESS);
service.startService();
我的SampleService
在什么时候告诉Windows已初始化?通过实验,我可以看到,如果在构造过程中发生运行时异常,则该服务的状态永远不会是SERVICE_RUNNING,因此该过程中有 something 可以设置该状态。但是我的一些构造函数在队列上等待或进入旋转循环,它们做设置了SERVICE_RUNNING状态,所以我不知道此状态的设置位置。 W32Service's documentation对此毫无用处。
答案 0 :(得分:0)
您的服务并没有真正作为常规服务公开,而是在进程中生成了JVM或单独将服务状态设置为运行时才依赖Procrun。在prunsrv.c
(具有用于procrun的服务容器代码)中,您可以检查serviceStart()
的调用方式以及成功后会发生什么。