Лучшая практика для написания самообновляющейся службы Windows
Нам нужно создать службу Windows, которая может самообновляться.
Три варианта spring для разума,
-
вторая служба, которая управляет извлечением, деинсталляцией и установкой первой службы.
-
Использование некоторых сторонних фреймворков (предложения приветствуются. Я считаю, что .NET поддерживает автоматическое обновление для приложений форм Windows, но не для служб Windows)
-
Использование модели плагина, в которой служба представляет собой всего лишь оболочку, содержащую логику обновления и запуска, а бизнес-логика службы содержится в DLL, которая может быть заменена.
Может ли кто-нибудь пролить свет на решение этой проблемы?
Спасибо
Ответы
Ответ 1
Просто некоторые мысли, которые у меня были.
1 кажется проблематичным, потому что вы в конечном итоге имеете дело с ситуацией, которую пытаетесь решить, потому что в какой-то момент обновление будет нуждаться в обновлении.
3 звучит хорошо, но если "поменять" вы имеете в виду использование какого-то причудливого отражения для загрузки DLL во время выполнения, я не уверен, что производительность станет проблемой.
Существует четвертый вариант, когда служба может порождать процесс обновления, который позволит ему, если необходимо, обновить исполняемый файл перед его запуском. Оттуда это простой вопрос о написании инсталляционного приложения, которое служба будет появляться незадолго до закрытия.
Ответ 2
Я использую опцию 1. Процесс обновления обновляется очень редко в эти дни. Он использует XML файл, содержащий сведения о том, где можно получить файлы (в настоящее время поддерживает SVN, работает над добавлением поддержки NuGet) и куда их поместить. Он также указывает, какие из них являются службами, а какие - веб-сайтами, и указывает имя службы, которая будет использоваться для каждого проекта.
Процесс проверяет исходный код, если есть новая версия, он копирует его в новый каталог с нумерованной версией и затем обновляет службу. Он также хранит 5 копий каждого обновления, что упрощает откат при возникновении проблемы.
Здесь основной фрагмент кода для обновления, который останавливает существующий сервис, копирует файлы и перезапускает его.
if (isService)
{
log.Debug("Stopping service " + project.ServiceName);
var service = GetService(project);
if (service != null &&
service.Status != System.ServiceProcess.ServiceControllerStatus.Stopped && service.Status != System.ServiceProcess.ServiceControllerStatus.StopPending)
{
service.Stop();
}
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped, new TimeSpan(0, 1, 0));
if (service.Status == System.ServiceProcess.ServiceControllerStatus.Stopped)
log.Debug("Service stopped");
else
log.Error("ERROR: Expected Stopped by Service is " + service.Status);
}
log.Debug("Copying files over");
CopyFolder(checkoutDirectory, destinationDirectory);
if (isService)
{
log.Debug("Starting service");
var service = GetService(project);
// Currently it doesn't create services, you need to do that manually
if (service != null)
{
service.Start();
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running, new TimeSpan(0, 1, 0));
if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)
log.Debug("Service running");
else
log.Error("Service " + service.Status);
}
}