Остановка службы в c ++, когда я использую функцию ExitProcess () - PullRequest
1 голос
/ 10 июня 2009

Я остановил службу в своем приложении, хотел узнать, что такое использование ExitProcess, и если я должен его использовать

Ответы [ 4 ]

2 голосов
/ 11 июня 2009

Вам никогда не нужно использовать ExitProcess(), чтобы остановить службу. На самом деле, вам никогда не нужно использовать ExitProcess() вообще.

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

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

Привилегии, необходимые для взаимодействия с SCM, менее опасны, чем те, которые требуются для завершения произвольного процесса, но обычно они не предоставляются вне группы «Администраторы».

Редактировать: Комментарий спросил об остановке службы изнутри.

Это может быть сложный вызов, особенно если служба находится в каком-то неудачном состоянии. Служба и SCM должны согласиться с тем, что служба останавливается, или SCM предпримет действие по восстановлению, настроенное для службы.

У меня есть полная реализация службы, которая может служить альтернативной точкой зрения на то, как справляться с некоторыми из этих вещей. Это LuaService и является платформой, которая позволяет (однопоточному) сервису быть реализованным в чистом Lua помимо самого исполняемого файла LuaService. В справочном руководстве делается попытка полностью документировать внутренние компоненты, а также документировать некоторые детали срока службы службы, которые в противном случае были задокументированы посредством взаимодействия различных статей в MSDN.

2 голосов
/ 10 июня 2009

Просмотрите OpenSCManager () , OpenService () и ControlService () вызовы Windows API. Обратите внимание, что ваша программа может не иметь необходимых разрешений для их вызова, поэтому может потребоваться повышение прав - см. Безопасность службы и Права доступа для получения дополнительной информации.

Существует также пример как остановить службу .

1 голос
/ 29 мая 2013

Я вижу, что ни один из постов здесь действительно не отвечает на оригинальный вопрос.

RBerteig писал: "В крайних случаях это приведет к перезагрузке системы."

Это чепуха. Это может произойти, если вы убьете WinLogon.exe, но он недействителен для служб в целом.

Если вы остановите службу из другого приложения, вы, очевидно, будете использовать

ControlService(mh_Service, SERVICE_CONTROL_STOP, &k_Status);

Но что, если служба решит, что ее работа выполнена, и она сама захочет выключиться?

Правильный путь таков (если ваша служба не работает в общем процессе):

void cService::Suicide()
{
    // Inform the Service Control Manager that the service is stopped now.
    SERVICE_STATUS k_Status = {0};
    k_Status.dwServiceType      = SERVICE_WIN32_OWN_PROCESS; 
    k_Status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    k_Status.dwCurrentState     = SERVICE_STOPPED;
    SetServiceStatus(mh_Service, &k_Status);

    ExitProcess(0);
}

Я использую этот код в своем классе обслуживания, и он отлично работает на любой версии Windows от XP до Windows 10.

! Очевидно, вы должны выполнить очистку , которая требуется перед вызовом этой функции!

0 голосов
/ 11 июня 2009

ExitProcess для завершения самого процесса (так же, как ExitThread завершает поток). Это используется для завершения процесса (программы или DLL), хотя Microsoft не рекомендует его для завершения DLL.

Если вы пытаетесь остановить себя (вы - процесс), вы можете использовать ExisProcess, хотя я бы порекомендовал более чистое отключение, чтобы убедиться, что все чисто остановлено. ExitProcess, как и ExitThread, останавливается без разматывания стека, поэтому деструкторы не вызываются.

Из службы вы останавливаетесь на основе внешнего сигнала. Вы можете ответить на это, вызвав ExitProcess, но, вероятно, было бы лучше иметь какую-то форму отключения, которая закрывает все необходимое и регистрирует это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...