Привет! Наконец удалось найти время для продолжения серии заметок про написание инсталляторов. В прошлых статьях мы рассмотрели создание простого инсталлятора, который умеет принимать от пользователя номер порта, на котором будет работать устанавливаемая служба.
В этой статье я хочу рассмотреть процесс обновления программного обеспечения. Сейчас нам для обновления нашей службы необходимо удалить предыдущую версию и установить новую. Если попробовать установить новую версию поверх старой, то старая версия удалена не будет. В системе останутся записи об обеих версиях, даже если мы установим их в одно место. Останется два комплекта ярлыков и два пункта с наименованием программы в элементе панели управления «Программы и компоненты». Такой режим ручного удаления и установки нам явно не очень удобен, и его необходимо автоматизировать.
WiX позволяет создавать три типа обновлений:
В этой статье я хочу рассмотреть процесс обновления программного обеспечения. Сейчас нам для обновления нашей службы необходимо удалить предыдущую версию и установить новую. Если попробовать установить новую версию поверх старой, то старая версия удалена не будет. В системе останутся записи об обеих версиях, даже если мы установим их в одно место. Останется два комплекта ярлыков и два пункта с наименованием программы в элементе панели управления «Программы и компоненты». Такой режим ручного удаления и установки нам явно не очень удобен, и его необходимо автоматизировать.
WiX позволяет создавать три типа обновлений:
- Major upgrade – самый простой тип обновлений, это обычный MSI инсталлятор, как мы создавали раньше. Отличие только в том, что если он обнаружит предыдущую версию продукта, то он ее удалит. То есть предыдущая установленная версия будет удалена, а новая будет установлена на чистое место. Данный подход требует изменения версии и кода продукта (об этом ниже).
- Minor upgrade обновляет существующие файлы без деинсталляции установленного продукта. Этот режим можно использовать для исправления дефектов или поставки новых фич и компонентов.
- Small update обычно поставляется в виде патча, в нем меньше по объему изменений чем minor upgrade.
Я не хочу приводить полный список различий этих трех типов обновлений. Вместо этого я сфокусируюсь на подготовке major upgrade, так как этот подход самый простой в реализации и самый, по-моему, понятный способ обновлений.
Итак, major upgrade – это полный инсталляционный пакет, который удаляет более старую версию продукта и устанавливает новую. Чтобы его создать, нужно выполнить следующие действия:
- В секции Product изменить значение элемента Id на новый Guid.
- Увеличить значение версии продукта (элемент Version в секции Product).
- Добавить и сконфигурировать секцию MajorUpgrade.
В качестве нового идентификатора продукта в элемент Id можно каждый раз подставлять новый Guid, но проще и удобней будет использовать значение * (звездочка). Это будет означать, что WiX будет сам подставлять новый идентификатор при каждой компиляции проекта.
Есть одно неочевидное замечание о версии продукта. Windows Installer игнорирует четвертую цифру в версии, поэтому при подготовке обновлений следует полагаться на первые три. Это рождает дополнительные проблемы при выпуске версий продукта, в которых меняется только номер сборки, и с этим приходится считаться.
Теперь секция Product будет выглядеть так:
<Product Id="*" Name="$(var.ProductName)" Language="1049" Version="$(var.Version)" Manufacturer="$(var.Manufacturer)" UpgradeCode="ceed7874-addb-4b86-af85-e6feb748b6c1">
Стоит отметить, что по сравнению с предыдущей версией тут был проведен небольшой рефакторинг: значения, которые могут измениться, были вынесены в переменные, и обращение к ним происходит по наименованиям. Для этого я создал в проекте файл Variables.wxi и перенес туда все значения, которые могут измениться. Файл выглядит так:
<?xml version="1.0" encoding="utf-8"?> <Include> <?define Version="1.0.1.0"?> <?define DefaultPort="8888"?> <?define ProductName="ApplicationInstaller"?> <?define Manufacturer="MySoftInc"?> <?define InstallLocation="ApplicationServer"?> </Include>
Далее я подключил этот файл к файлу Product.wxs с помощью директивы <?include Variables.wxi?> и заменил значения на наименования переменных. Имя переменной выглядит так $(var.Version), где после var. идет собственно наименование переменной.
Последним этапом осталось настроить секцию MajorUpgrade. Если этого не сделать, то при установке новой версии старая не будет удалена. И их обе можно будет увидеть в элементе панели управления «Программы и компоненты». Добавим в файл Product.wxs следующую секцию перед описанием директорий установки.
<MajorUpgrade DowngradeErrorMessage="Более новая версия [ProductName] уже установлена." Schedule="afterInstallExecute"/>
При попытке установить более старую версию поверх новой будет выведено сообщение «Более новая версия ApplicationInstaller уже установлена», и установка будет прекращена. Значение элемента Schedule говорит о том, что сначала будет установлена новая версия, и только потом будет удалена старая. Если по какой-то причине возникнет сбой при установке, то установка откатится до предыдущей версии.
Теперь инсталлятор готов и умеет сам себя обновлять. Исходники примера можно взять здесь (папка WixExample3).
Комментариев нет:
Отправить комментарий