TL;DR:我有一个用 Java 编写的 Windows 服务,经过 jarred 处理,并与 Procrun 一起安装。我从W32Service.startService()
. 该服务何时告诉 Windows 它已启动?
我正在使用用 Java 编写的 Windows 服务。我一直在使用Procrun来安装它们,并使用 JNA 来使用它们(特别是com.sun.jna.platform.win32.W32Service)。
我想了解对象方法的确切行为(这是我的 Y 的 X:了解的确切行为)。W32Service
waitForNonPendingState()
startService()
waitForNonPendingState()
实际上非常简单:它会轮询服务的状态,直到它处于非挂起状态或发生超时。不过,服务如何转换到非挂起状态并不是那么简单。
微软的服务状态转换页面说:
服务的初始状态是 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,因此该进程中有一些东西设置了该状态。但是我的一些构造函数等待队列或进入自旋循环,他们确实设置了 SERVICE_RUNNING 状态,所以我不知道这个状态是在哪里设置的。W32Service 的文档在这方面并没有什么用处。