Java Windows服务如何“知道”它已完成初始化?

时间:2018-07-11 13:38:08

标签: java windows service jna procrun

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对此毫无用处。

1 个答案:

答案 0 :(得分:0)

您的服务并没有真正作为常规服务公开,而是在进程中生成了JVM或单独将服务状态设置为运行时才依赖Procrun。在prunsrv.c(具有用于procrun的服务容器代码)中,您可以检查serviceStart()的调用方式以及成功后会发生什么。