У меня есть служба Windows, построенная на классе CAtlServiceModuleT
ATL 7. Эта служба обслуживает COM-объекты, которые используются различными приложениями в системе, и эти другие приложения, естественно, начинают получать ошибки, если служба остановлена, пока они еще работают.
Я знаю, что библиотеки ATL решают эту проблему, возвращая S_OK в DllCanUnloadNow()
, если GetLockCount()
в CComModule возвращает 0. То есть он проверяет, что никто не использует COM-объекты, обслуживаемые DLL. Я хочу эквивалентную функциональность в сервисе.
Вот что я сделал в моем переопределении CAtlServiceModuleT::OnStop()
:
void CMyServiceModule::OnStop()
{
if( GetLockCount() != 0 ) {
return;
}
BaseClass::OnStop();
}
Теперь, когда пользователь пытается остановить службу с панели «Службы», ему выдается сообщение об ошибке:
Windows не удалось остановить службу XYZ на локальном компьютере.
Служба не вернула ошибку. Это может быть внутренняя ошибка Windows или внутренняя ошибка службы.
Если проблема не устранена, обратитесь к системному администратору.
Запрос на остановку действительно отклонен, но, по-видимому, сервис находится в плохом состоянии. Второй запрос на остановку приводит к этому сообщению об ошибке:
Windows не удалось остановить службу XYZ на локальном компьютере.
Ошибка 1061: в данный момент служба не может принимать управляющие сообщения.
Интересно, что служба на самом деле останавливается в этот раз (хотя я бы предпочел этого не делать, поскольку все еще имеются выдающиеся ссылки на COM).
У меня два вопроса:
- Считается ли плохой практикой отказ от остановки при запросе?
- Есть ли вежливый способ показать, что в запросе Stop отказано; тот, который не переводит Сервис в плохое состояние?