Я работаю над установщиком, который копирует файлы в Program Files, а затем запускает службу (через один из скопированных файлов). При первой установке это будет работать без проблем, но проблемы начинают возникать, когда программа установки запущена, а служба уже запущена на машине. Это связано с тем, что установщик пытается заменить файлы, которые уже существуют в Program Files, но один из этих файлов используется службой Windows, поэтому его нельзя заменить, пока служба не будет остановлена.
Поэтому я решил использовать API ServiceController, чтобы остановить службу в начале установки, установить файлы (перезаписав существующие файлы) и снова запустить службу. Кода очень мало, но вот он:
Создайте экземпляр ServiceController:
try
{
service = new ServiceController(serviceName);
}
catch (InvalidOperationException ioe)
{
// ...
}
Остановка службы:
if (service.Status != ServiceControllerStatus.Stopped)
{
service.Stop();
}
Затем дождитесь остановки службы и установите файлы:
service.WaitForStatus(ServiceControllerStatus.Stopped);
// install files...
И, наконец, перезапустите службу:
service.Start();
С этим кодом метод service.WaitForStatus()
будет просто ждать вечно (или дольше, чем я готов ждать, по крайней мере, до часа). Странно то, что я могу запустить этот код, записать service.Status()
в журнал, проверить службу вручную, чтобы убедиться, что она остановлена, проверить журнал и увидеть, что ServiceController считает, что служба все еще работает.
Сначала я подумал, что проблема связана с service.Stop()
, поэтому я попытался создать пару объектов Process
, которые получили PID службы, а затем убили задачу, которая мгновенно останавливает службу, но все равно ServiceController
не распознает, что служба остановлена. Если я удалю метод service.WaitForStatus()
из своего кода, будет выдано исключение, поскольку программа установки пытается перезаписать файл, используемый службой.
Кроме того, я пробовал это с разными службами, но результат всегда один и тот же, что заставляет меня поверить, что проблема не в самой службе.
Почему ServiceController
не распознает, что служба остановлена? Есть ли решение или обходной путь этой проблемы? Я работаю с .NET 2.0, поэтому все, что требует выше, к сожалению, не для меня. Ваше здоровье.