Начиная с csharp-example и должным образом отмечая связанные вопросы SO (Перезапустить службы Windows от С# и Невозможно перезапустить службу) и различные другие вопросы, связанные с перезапуском только одной службы, мне интересно, какой лучший метод для перезапуска службы с зависимыми службами (например, Message Queuing
, от которого зависит Message Queuing Triggers
или IIS
, от которого зависят FTP Publishing
и World Wide Web Publishing
). Захват mmc делает это автоматически, но код, похоже, не обеспечивает такую же функциональность (по крайней мере, не так легко).
Документация MSDN для Stop говорит: "Если какие-либо службы зависят от этой службы для их работы, они будут остановлены до остановки этой службы. Свойство DependentServices содержит набор сервисов, которые зависят от этого:" и DependentServices
возвращает массив служб. Предполагая, что StartService()
и StopService()
следуют соглашениям, изложенным в примерах и указанным выше (за исключением того, что они принимают непосредственно ServiceControllers
и TimeSpans
), я начал с:
public static void RestartServiceWithDependents(ServiceController service, TimeSpan timeout)
{
ServiceController[] dependentServices = service.DependentServices;
RestartService(service, timeout); // will stop dependent services, see note below* about timeout...
foreach (ServiceController dependentService in dependentServices)
{
StartService(dependentService, timeout);
}
}
Но что, если служебные зависимости являются вложенными (рекурсивными) или циклическими (если это возможно...) - если Service A
зависит от Service B1
и Service B2
и Service C1
зависит от Service B1
, кажется, что "перезагрузка" Service A
этим методом остановит Service C1
, но не перезапустит его...
Чтобы сделать этот пример более четким, я буду следовать модели в оснастке mmc:
The following system components depend on [Service A]:
- Service B1
- Service C1
- Service B2
Есть ли лучший способ обойти это, или ему просто придется рекурсивно входить и останавливать каждую зависимую службу, а затем перезапускать их после перезапуска основной службы?
Кроме того, будут ли зависимые, но в настоящее время остановленные службы перечислены в DependentServices? Если да, то это не перезапустит их? Если да, то следует ли нам это контролировать? Это просто кажется более беспорядочным и беспорядочным...
* Примечание. Я понимаю, что timeout
здесь не применяется полностью (общий тайм-аут может быть много раз длиннее, чем ожидалось), но на данный момент это не проблема, о которой я беспокоюсь - если вы хотите исправьте это, отлично, но не просто говорите, что "тайм-аут сломан..."
Обновление: После некоторого предварительного тестирования я обнаружил (/подтвердил) следующие варианты поведения:
- Остановка службы (например,
Service A
), от которой зависят другие службы (например,Service B1
), остановит другие службы (включая "вложенные" зависимости, такие какService C1
) -
DependentServices
включает в себя зависимые службы во всех состояниях (Running, Stopped и т.д.), а также включает вложенные зависимости, т.е.Service_A.DependentServices
будет содержать{Service B1, Service C1, Service B2}
(в этом порядке, посколькуC1
зависит отB1
). - Запуск службы, которая зависит от других (например,
Service B1
зависит отService A
), также запустит необходимые услуги.
Таким образом, приведенный выше код может быть упрощен (по крайней мере частично), чтобы просто остановить основную службу (которая остановит все зависимые службы), а затем перезапустить наиболее зависимые службы (например, Service C1
и Service B2
) (или просто перезапустив "все" зависимые сервисы - он пропустит уже запущенные), но это действительно просто мгновенно отменяет запуск основной службы, пока одна из зависимостей не пожалуется на нее, так что это действительно не помогает.
Ищите теперь, как только перезапуск всех зависимостей является самым простым способом, но который игнорирует (на данный момент) управление уже остановленными службами и такими...