winapi — правильный способ регистрации для уведомления перед отключением от переполнения стека

Я пишу локальное приложение-службу, используя C ++, и не могу найти правильный способ регистрации для предварительного уведомления о завершении работы (для ОС более поздней, чем Windows XP). Я считаю, что SERVICE_CONTROL_PRESHUTDOWN уведомление было добавлено с Vista, но когда вы вызываете SetServiceStatus, нам нужно указать:

dwServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_PRESHUTDOWN;

или же

dwServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PRESHUTDOWN;

4

Решение

Вы не можете согласиться с отключением и предварительным отключением, если ваша служба правильно закодирована. Документация прямо заявляет об этом.

От http://msdn.microsoft.com/en-us/library/windows/desktop/ms683241(v=vs.85).aspx:

Ссылаясь на SERVICE_CONTROL_PRESHUTDOWN: «Служба, которая обрабатывает это уведомление, блокирует выключение системы пока сервис не остановится или истекает интервал ожидания предварительного отключения, указанный в SERVICE_PRESHUTDOWN_INFO. »

На той же странице раздел о SERVICE_CONTROL_SHUTDOWN добавляет: «Обратите внимание, что службы, которые регистрируются для уведомлений SERVICE_CONTROL_PRESHUTDOWN не может получить это уведомление, потому что они уже остановились

Таким образом, правильным способом является установка dwControlsAccepted для включения либо SERVICE_ACCEPT_SHUTDOWN, либо SERVICE_ACCEPT_PRESHUTDOWN, в зависимости от ваших потребностей, но не для обоих одновременно.

Но обратите внимание, что вы, вероятно, хотите принять больше элементов управления. Вам следует всегда разрешить хотя бы SERVICE_CONTROL_INTERROGATEи почти наверняка позволит SERVICE_CONTROL_STOPпоскольку без последнего служба не может быть остановлена ​​(например, для удаления программного обеспечения), и процесс должен быть принудительно завершен (т.е. убитый).

7

Другие решения

Как отмечалось в комментариях выше, вам нужно будет выбрать либо SERVICE_ACCEPT_SHUTDOWN, либо SERVICE_ACCEPT_PRESHUTDOWN (Vista или более поздняя версия). Если вы используете SERVICE_ACCEPT_PRESHUTDOWN, вам нужно будет зарегистрировать свой сервис в SCM, используя RegisterServiceCtrlHandlerEx вместо RegisterServiceCtrlHandler, иначе вы не будете получать уведомления перед отключением. Прототип обработчика также изменяется с Handler на HandlerEx.

Следует также отметить, что обработка событий чистого отключения ограничена 5 секундами в Windows Server 2012 (и, вероятно, Windows 8), 12 секундами в Windows 7 и Windows Server 2008, 20 секундами в Windows XP до остановки службы при остановке. Это причина, почему вам может потребоваться уведомление перед отключением. Вы можете изменить это в \\ HKLM \ SYSTEM \ CurrentControlSet \ Control \ WaitToKillServiceTimeout.

2

Эти два уведомления кажутся разными, как я понял из документации. Если вам действительно нужно, чтобы ваша служба получила уведомление перед отключением, вам необходимо: dwServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_PRESHUTDOWN; Но если вы также хотите, чтобы ваша служба получала уведомления о завершении работы, вам следует воспользоваться вторым вариантом.

0
По вопросам рекламы [email protected]