- PVSM.RU - https://www.pvsm.ru -
Добрый день всем! Хочется поделиться со всеми своим опытом создания системы для генерации патчей (да простит меня читатель за использование этого слова). Про wix довольно много было написано здесь [1] и я предполагаю, что читатель немного знаком с ним, а вот проблему создания патчей как-то обошли. В нашей же компании они нашли широкое применение, в основном из-за своего размера, а также из-за возможности отката.
Для начала я опишу задачу, с которой я столкнулся, затем опишу базовую информацию для создания патчей. Также сделаю 2-ю часть с конкретным примером, утилитами для упрощения этого процесса и исходниками.
1. Есть узкоспециализированный desktop продукт, который устанавливается по многим субъектам РФ в многие филиалы инстанции, связанной с лесным хозяйством. Давайте для удобство дадим имя этому условному продукту, допустим Ясень.
2. Для каждого субъекта собирается своя версия инсталляции, которые не отличаются бинарниками, а отличаются контент файлами, которые не меняются (карты, шаблоны отчетов, базовая БД и т.д.).
3. В «горячий» сезон обновления выпускаются раз в 1-2 недели (всем резко становится что-то нужно и часто что-то новое). При этом версия продукта меняется (либо major, minor или build)
4. В любой момент любой клиент может попросить как обновление, так и полную версию. Надо выйти из положения минимальными затратами.
5. ClickOnce не подходит, так как некоторые госструктуры, как ни странно, не имеют прямого выхода в интернет, либо он очень плох.
6. Сделать все на Wix, так как он бесплатен.
В этих условиях (пункт 4!), чтобы экономить трафик и не слать каждый раз по 100 Мб полной версии много раз лучше делать патчи.
Есть и пара прихотей разработчиков:
1. А также хочется свободы в пропусках патчей, то есть можно, например, обновляться через 1 или 2 обновления.
2. На схеме возможных обновлений эта прихоть выглядит так:
То есть, разрешены все варианты последовательности:
• Последовательно получать все патчи, потом получить полную msi (сплошная линия).
• Пропустить 2 патча, поставить 3-й, а потом поную msi (пунктирная).
• Поставить 1 патч, 1 пропустить, следующий поставить и получить полную версию msi.
• и т.д.
Давайте начнем с начала.
Как известно, версия в Wix состоит (=учитывает) из 3-х чисел: x.y.z, x — Major version, y — Minor version, z — Build number. Принцип изменения этих значений, на мой взгляд, определяется компанией, и какого-то явного правила нет, только — рекомендации [2].
В то же время, существует 3 типа обновлений:
Реализации перечисленных вариантов обновления в Wix базируется на 2-х переменных:
1. Атрибут UpgradeCode элемента Product.
2. Атрибут ProductCode элемента Product.
Про Package.Id мы не говорим, так как он меняется почти всегда. Подробно о том, когда менять UpgradeCode и ProductCode, написано тут [3] и тут [4].
Вкратце это так:
Пусть есть уже установленное приложение версии 1.0, мы создаем следующую версию инсталляции. Мы можем в ней поменять UpgradeCode и ProductCode на новое значение относительно предыдущей версии.
Давайте посмотрим, что получится, если мы поменяемоставим старым значения этих атрибутов. Наш успех при попытке (1) создать пакет и (2) установить его отражен в таблице ниже:
Мы получим: * — minor update, ** — major update, *** — small update
Сама процедура создания патча в общем выглядит очень просто: есть одна или несколько «базовых» сборок и одна «конечная». Утилита генерации патчей создает пакет, который умеет обновлять продукт с версий, которые содержатся в «базовых» сборках, до версии, которая содержится в «конечной».
Как известно, Wix поддерживает 2 технологии создания патчей: используя PatchWiz.dll и сам Wix. Я не буду глубоко залезать в разборы всех достоинств и недостатков этих вариантов. Это не является целью статьи. Скажу лишь, что в результате проведенных опытов мы остановились на первом варианте (т.к. только на нем смогли получить удовлетворяющий нас результат).
Для создания патча с использованием PatchWiz (будем использовать утилиту msimsp.exe) необходимо минимум 2 инсталляционных пакета (точнее 2 msi файла) и описатель патча (обычно файл называют Patch.wxs). Я не буду подробно описывать все возможности, которые им предусмотрены, иначе статья получится слишком большой, но основные моменты затрону. (Подробности можно накопать тут [5])
1. Сначала создается Patch.wxs, а в нем элемент PatchCreation [6].
<PatchCreation
Id="{42D7EE3B-A712-4AD4-9B23-A8710FC486FA}"
Codepage="1251"
CleanWorkingFolder="yes"
OutputPath="patch.pcp"
WholeFilesOnly="yes">
Здесь:
Id – уникальный Id патча, всегда новый.
Codepage – кодовая страница для промежуточного (для нас) файла с расширение PCP.
CleanWorkingFolder – очищать временную папку после создания патча.
OutputPath – путь и имя промежуточного файла.
WholeFilesOnly – в патч будем включать изменившиеся файлы целиком, а не только изменившиеся блоки в них.
Внутрь PatchCreation записываются элементы с информацией о патче, здесь, я думаю, все понятно (PatchMetadata – не обязательный элемент).
<PatchInformation
Description="Обновление Ясень"
Comments="Обновление Ясень до 1.1"
Manufacturer="Рога и копыта"/>
<PatchMetadata
AllowRemoval="yes"
Description="Обновление Ясень"
ManufacturerName="Рога и копыта"
TargetProductName="Ясень"
MoreInfoURL="http://рогаикопыта.рф/"
Classification="Update"
DisplayName="Обновление Ясень до версии 1.1"/>
И, пожалуй, главное: указываем пути, где лежат базовые сборки и конечная.
<Family DiskId="2" Name="Yasen" SequenceStart="5000">
<UpgradeImage SourceFile="C:WorkYasenv1.1Setup.msi" Id="NewPackage">
<TargetImage SourceFile="C:WorkYasenv1.0.8Setup.msi" Order="2" Id="BasePackage1"/>
<TargetImage SourceFile="C:WorkYasenv1.0Setup.msi" Order="3" Id="BasePackage2"/>
</UpgradeImage>
</Family>
Здесь:
DiskId – номер новой записи в таблице Media, не должен совпадать с Media [7] Id базового установщика.
Name – имя линейки обновлений. Обновлять один продукт обновлениями с разными Family Name я не пробовал.
SequenceStart – номер для записи в таблице InstallExecuteSequence, не должен совпадать с существующими записями. В большинстве примеров, которые я видел, стоит 5000. Это значение не конфликтует со стандартными значениями Wix, в нашем пакете тоже это значение не используется. (Подробно про это есть в статьи про wix, перечисленные выше)
Элемент UpgradeImage – описывает конечную сборку.
SourсeFile – путь к конечной сборке (на самом деле не совсем на нее, а на ее «распакованную» версию, об этом написано ниже)
Id – идентификатор сборки.
Элемент TargetImage – описывает те сборки, которые могут быть обновлены текущим обновлением.
SourceFile – путь к базовой сборке.
Order – порядок базовых сборок (так и не понял, зачем это надо).
Id – идентификатор базовых сборок.
И в конце PatchCreation вставляется элемент PatchSequence
<PatchSequence
PatchFamily= "Yasen"
Sequence="1.1.0.0"
Supersede="yes"
ProductCode="{7381ABA7-774B-4D44-BD7B-0A90BBCF2B0A}"
/>
Здесь:
PatchFamily – указывает к какой линейке относится этот патч (где-то мы это видели уже?)
Sequence – указывает версию патча, чтобы отличать в каком порядке патчи были выпущены. Указывается в формате x.x.x.x.
Supersede – указывает, может ли этот патч отменять все предыдущие патчи (накопительный патч?)
ProductCode – код продукта (видимо, чтобы не ошибиться).
После того, как инсталляции и описатель патча готовы, надо сделать следующее:
1. Выполнить административную установку всех инсталляций в отдельные папки, например, так:
msiexec.exe /a 1.0product.msi /qb TARGETDIR=C:sample1.0admin
msiexec.exe /a 1.1product.msi /qb TARGETDIR=C:sample1.1admin
Обратите внимание, что путь к инсталляциям в PatchCreation должен указывать на эти «распакованные» версии, например, C:sample1.0adminproduct.msi
2. Компилируем Wix файлы:
candle.exe patch.wxs
light.exe patch.wixobj -out patch.pcp
3. Используем утилиту от PatchWiz:
msimsp.exe -s patch.pcp -p patch.msp -l patch.log
И мы, наконец, получили желаемое!
Мы получили желаемый патч, однако для решения поставленной задачи нужно нечто большее:
Соответственно для решения этих неудобств я напишу вторую часть и опишу все, что обещал в начале поста.
Ссылки:
Wix tutorial (очень хорошее руковдоство) [8]
Wix — Creating patches [9]
MSDN — Patching and Upgrades [10]
Автор: neisbut
Источник [11]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/news/41231
Ссылки в тексте:
[1] здесь: http://habrahabr.ru/search/?q=wix
[2] рекомендации: http://en.wikipedia.org/wiki/Software_versioning
[3] тут: http://msdn.microsoft.com/en-us/library/windows/desktop/aa367850(v=vs.85).aspx
[4] тут: http://msdn.microsoft.com/en-us/library/windows/desktop/aa372399(v=vs.85).aspx
[5] тут: http://wix.sourceforge.net/manual-wix3/patch_building.htm
[6] PatchCreation: http://wix.sourceforge.net/manual-wix2/wix_xsd_patchcreation.htm
[7] Media: http://wix.sourceforge.net/manual-wix2/wix_xsd_media.htm
[8] Wix tutorial (очень хорошее руковдоство): http://wix.tramontana.co.hu/tutorial/upgrades-and-modularization
[9] Wix — Creating patches: http://wix.sourceforge.net/manual-wix3/patching.htm
[10] MSDN — Patching and Upgrades: http://msdn.microsoft.com/en-us/library/windows/desktop/aa370579(v=vs.85).aspx
[11] Источник: http://habrahabr.ru/post/190546/
Нажмите здесь для печати.