Как служба Windows Java "узнает", что она завершила инициализацию?
TL; DR: у меня есть служба Windows, написанная на Java, jarred и установленная с Procrun. Я начинаю это с W32Service.startService()
, Когда служба сообщает Windows, что она запустилась?
Я работаю со службами Windows, написанными на Java. Я искал и использовал Procrun для их установки и JNA для работы с ними (в частности, com.sun.jna.platform.win32.W32Service).
Я хотел бы понять точное поведение W32Service
объекты waitForNonPendingState()
метод (который является X к моему Y: понять точное поведение startService()
).
waitForNonPendingState()
на самом деле очень просто: он опрашивает статус сервиса, пока он не будет в состоянии ожидания или пока не истечет время ожидания. Как сервис переходит в состояние ожидания, пока не так просто.
Страница Microsoft Service State Transitions сообщает:
Начальное состояние службы - SERVICE_STOPPED. Когда SCM запускает службу, он устанавливает состояние службы SERVICE_START_PENDING и вызывает функцию ServiceMain службы. Служба затем завершает свою инициализацию, используя один из методов, описанных в Service ServiceMain Function. После того, как служба завершает свою инициализацию и готова начать получать запросы управления, служба вызывает SetServiceStatus, чтобы сообщить SERVICE_RUNNING...
Но это на самом деле не проливает свет на то, как сервис делает это. Замечания ServiceMain также просто говорят: " Диспетчер управления службами (SCM) ожидает, пока служба не сообщит о состоянии SERVICE_RUNNING. "; это довольно точно, насколько я могу найти.
Что приводит меня к моему вопросу: как служба Windows Java "узнает", что она завершила инициализацию?
Другими словами, если у меня установлена служба с 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
скажите винду это инициализировали? Экспериментируя, я вижу, что если во время конструирования возникает исключение во время выполнения, статус сервиса никогда не будет SERVICE_RUNNING, поэтому в этом процессе есть что- то, что устанавливает этот статус. Но некоторые из моих конструкторов ждут очереди или входят в циклы вращения, и они устанавливают статус SERVICE_RUNNING, поэтому я не могу сказать, где этот статус установлен. Документация W32Service на это не годится.
1 ответ
Ваш сервис на самом деле не отображается как обычный сервис, он полагается на Procrun, как только JVM порождается как часть процесса или отдельно устанавливается состояние сервиса. В prunsrv.c
который имеет код контейнера службы для procrun, вы можете проверить, как serviceStart()
называется и что происходит на успех.