Как служба 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() называется и что происходит на успех.

Другие вопросы по тегам