Идентифицируемый код при завершении процесса - PullRequest
4 голосов
/ 10 октября 2011

У меня есть старый добрый Windows-сервис (наследующий от System.ServiceProcess.ServiceBase), к которому я добавил компонент (реализующий IComponent) с помощью this.components.Add(new MyStuff());
Однако Disposable() MyStuff не запускается, если я закрываю exe из диспетчера задач.

Возможные подозреваемые:

  • Ничто не работает на "Завершить процесс". Если да, то как мне убрать за собой (например, убить запущенные процессы?)
  • В целях тестирования я запускаю службу с

    var service = new MyService();<br> service.Run();<br> Thread.Wait(Timeout.Infinite);

    вместо ServiceBase.Run(new []{new MyService()}); может ли это быть проблемой?

  • ServiceBase не очищается автоматически. Если да, что мне делать?

Пожалуйста, помогите!

Дополнительная информация: я пытаюсь закрыть другие exe-файлы, которые я запустил из моего сервиса, используя Process.Start (...), поэтому, если есть способ сделать их автоматическим отключением (дочерний процесс?), Это тоже хорошо.

Ответы [ 3 ]

2 голосов
/ 10 октября 2011

Если вы «потянете за вилку», вы ничего не сможете сделать в этот момент. Это не считается контролируемым отключением. Это совершенно неожиданно, и ничто не даст вам возможности справиться с этим изнутри убитого процесса. Это даже не считается отключением. Чтобы было ясно: вы не выключаете, вы убиваете это! Это все равно, что вырывать шнур питания из компьютера и ожидать, что он аккуратно отключится. Не получится (хотя у меня был тестер, напиши мне этот очень точный тестовый пример несколько лет назад ...)

Решите это:

  • Ваши дочерние процессы должны будут "пропинговать" родительский процесс. Если он не отвечает, вы знаете, что что-то не так, и корректно завершите работу.

  • Или обратитесь к ответу ChrisBint (Service Controller). Получить сервис по имени, запустить и остановить его.

Найдите пример кода здесь: http://www.csharp -examples.net / рестарт-окна-сервис /

2 голосов
/ 10 октября 2011

Мой типичный способ обнаружения смерти родителя:

  • Во время родительского запуска создайте красивое длинное случайное имя
  • Также во время запуска получите именованный мьютекс с этим именем и сохраняйте его заблокированным на время жизни родителя.
  • При запуске дочернего процесса передайте длинное случайное имя в качестве параметра
  • У детей выделите поток, который пытается получить мьютекс с тем же именем.
  • Если ребенок когда-либо получит мьютекс, родительский процесс должен был умереть, поэтому ребенок должен также выйти

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

2 голосов
/ 10 октября 2011

Почему вы останавливаете службу с помощью диспетчера задач, вы в основном убиваете ее, не прося, чтобы она что-то сделала.

Поместите некоторый код в метод OnStop для очистки и используйте Service Manager для остановки / запускауслуга.

...