Я унаследовал службу Windows, написанную на C #.В редких условиях это плохо.Тем не менее, не совсем ясно, как потерпеть неудачу.Росс Беннетт изящно излагает проблему на bytes.com .Ради простоты я просто процитирую его здесь.
Привет, народ!
Я искал это повсюду, но, похоже, не могу пошатнутьсялюбая документация из MSDN или из Google.Я просмотрел каждую статью .NET по разработке служб Windows в расположенном там MSDN.
Я занимаюсь разработкой приложения службы Windows.Эта служба считывает данные своей конфигурации из системного реестра (HKLM), где она была размещена другим приложением «менеджера».Никаких проблем там нет.
Служба использует рабочий поток для своей работы.Поток создается в OnStart () и сигнализируется / присоединяется / удаляется в OnStop ().Опять же, никаких проблем.
Все прекрасно работает, когда:
- Системный администратор все настроил правильно, и
- все ресурсы внешней сети доступны.
Но, конечно, мы, как разработчики, просто не можем положиться на:
- Системный администратор все настроил правильно или
- сторонняя сетьресурсы достижимы.
Действительно, нам нужно, чтобы приложение-служба могло каким-то образом умирать самостоятельно.Если сетевой ресурс отключается, нам нужно остановить службу.Но, что более важно, нам нужно, чтобы СКМ знал, что он остановился сам по себе.SCM должен знать, что служба "отказала" ... и не была просто кем-то закрыта.
Вызов «return» или создание исключения в методе «OnStart ()» не являетсядаже полезно для служб, которые все еще находятся в процессе запуска. SCM весело работает, и процесс продолжает выполняться в диспетчере задач - хотя на самом деле он ничего не делает, поскольку рабочий поток никогда не создавался и не запускался.
Использование экземпляра ServiceController также не делает этого.Для SCM это выглядит как нормальное завершение работы, а не сбой службы.Таким образом, ни одно из действий восстановления или перезагрузки не происходит.(Также есть документация MSDNful, предупреждающая об опасностях потомка ServiceBase, использующего ServiceController, чтобы заставить вещи происходить с самим собой.)
Я читал статьи, в которых люди возились с вызовами PInvoking только для собственного кодаустановить флаг состояния «Остановлен» в SCM.Но это не останавливает процесс, в котором работает служба.
Мне бы очень хотелось узнать о предполагаемом способе:
- Выключение службы изнутри службыгде
- SCM надлежащим образом уведомлен о том, что служба «Остановлена», и
- Процесс исчезает из диспетчера задач.
Решения, включающие ServiceControllers don 't кажется подходящим, хотя бы потому, что 2 не выполняется.(Между прочим, документация Framework специально противопоказывает действия, которые имеют большой вес).
Буду признателен за любые рекомендации, указания на документацию или даже аргументированные предположения.:-) Ой!И я очень рад, что я упустил это.
Сердечно,
Росс Беннетт