Я понял это и подумал, что выложу ответ здесь для дальнейшего использования другими. Итак, я полностью объяснил проблему, я углублюсь в сценарий реального мира.
У нас есть довольно крупное программное обеспечение, которое требует от нас нескольких вспомогательных приложений, работающих на нескольких разных серверах. Наш текущий прогресс обновлений делает умеренно сложным обновление кода надежным способом. В настоящее время мы используем самораспаковывающиеся exe-файлы для развертывания нашего кода на разных серверах. Проблема возникает, когда у нас так много поддерживающих приложений, что становится трудно убедиться, что приложения установлены правильно с правильными настройками конфигурации и т. Д. Чтобы решить эту проблему, мы рассматриваем возможность вместо сжатия каждого из Поддерживая приложения, мы создаем единый установщик (MSI), который позволит команде инфраструктуры установить определенный набор вспомогательных приложений для каждой машины. Когда у нас будет существенное изменение (например, с 1.0 до 2.0), мы сделаем полную установку обновления (то есть все службы / процессы должны быть остановлены, удалены, установлены и запущены.) Когда у нас есть незначительное изменение, мы хотели бы только остановить и переустановить затронутые службы / процессы, не затрагивая другие приложения. Теперь, хватит мне бродить, давайте доберемся до решения:
Я изменил WIX Product.wxs, чтобы удалить ярлыки, так как они нам не нужны в нашем сценарии. Вот обновленный файл wxs:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="13C373D3-5C27-487e-A020-C2C89E4607B1" Name="HelloWorldInstaller" Language="1033" Version="1.0.0.0"
Manufacturer="HelloWorldInstaller" UpgradeCode="E7CB3C76-4D51-48a8-BFB4-6D11B2E2E65B">
<Package InstallerVersion="200" Compressed="yes" />
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
<FeatureRef Id="HelloWorld1Feature" />
<FeatureRef Id="HelloWorld2Feature" />
<FeatureRef Id="HelloWorld3Feature" />
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="Hello World" />
</Directory>
<Directory Id="DesktopFolder" Name="Desktop"/>
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="INSTALLLOCATION">
<Directory Id="HelloWorld1Directory" Name="Hello World 1">
<Component Id="HelloWorld1Component" Guid="6D1D9D33-DA17-4db3-8132-C39F32200C3A">
<File Id="HelloWorld1.exe" Name="HelloWorld1.exe" Source="HelloWorld1.exe" DiskId="1" Checksum="yes" />
</Component>
</Directory>
<Directory Id="HelloWorld2Directory" Name="Hello World 2">
<Component Id="HelloWorld2Component" Guid="B2D51F85-358B-41a7-8C45-B4BB341158F8">
<File Id="HelloWorld2.exe" Name="HelloWorld2.exe" Source="HelloWorld2.exe" DiskId="1" Checksum="yes" />
</Component>
</Directory>
<Directory Id="HelloWorld3Directory" Name="Hello World 3">
<Component Id="HelloWorld3Component" Guid="A550223E-792F-4169-90A3-574D4240F3C4">
<File Id="HelloWorld3.exe" Name="HelloWorld3.exe" Source="HelloWorld3.exe" DiskId="1" Checksum="yes" />
</Component>
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<Feature Id="HelloWorld1Feature" Title="Hello World 1" Level="1">
<ComponentRef Id="HelloWorld1Component"/>
</Feature>
</Fragment>
<Fragment>
<Feature Id="HelloWorld2Feature" Title="Hello World 2" Level="1">
<ComponentRef Id="HelloWorld2Component"/>
</Feature>
</Fragment>
<Fragment>
<Feature Id="HelloWorld3Feature" Title="Hello World 3" Level="1">
<ComponentRef Id="HelloWorld3Component"/>
</Feature>
</Fragment>
</Wix>
Теперь, наряду с этим, для наших небольших обновлений мы будем выпускать исправления для наших компонентов.
Например, допустим, у нас есть ProductA, который имеет три компонента - 1,2 и 3. Эти три компонента должны запускаться либо как службы, либо как запланированные задачи. Характер нашего продукта, мы не можем закрыть все наши службы, чтобы обновить или исправить один из наших компонентов. Итак, если после установки версии 1.0 мы обнаружим ошибку в компоненте 2, но мы не хотим, чтобы исправление, применяемое к этой ошибке, затронуло 1 или 3, мы выпустим патч для компонента 2, таким образом, будет затронут только компонент 2.
Для нашего быстрого примера, приведенного выше, мы используем HelloWorld1, HelloWorld2 и HelloWorld3 в качестве трех компонентов в нашем программном приложении. Мысль заключается в том, что мы должны иметь возможность установить все три с одним MSI, но затем обновить каждый независимо, не затрагивая другие установленные компоненты.
Итак, чтобы продемонстрировать это, я создал три консольных приложения, которые будут отображать «Hello World 1!», «Hello World 2!» И «Hello World 3!». Затем, после того, как мы выпустим исходный MSI, допустим, что мы нашли «ошибку», которая заставляет HelloWorld1 сказать «Hello World 1! Обновлено». вместо. Вот что мы будем делать, чтобы смоделировать это:
- Создайте Product.wixobj, выполнив эту команду в командной строке:
candle.exe Product.wxs
Помните, что для того, чтобы вызвать свечу или любую из команд WIX, в каталоге установки Wix должно быть в вашей переменной PATH. ( Краткое руководство по обновлению переменной среды PATH ) Кроме того, выполните команды в том же каталоге, что и файл Product.wxs.
- Создайте первую версию своего продукта (скажем, 1.0):
light.exe Product.wixobj -out ProductA-1.0.msi
- Теперь найдите ошибку (измените вывод HelloWorld1 на «Hello World 1! Обновлено.»), Затем обновите версию сборки и версию файла . Это важно, так как это то, как WIX может сказать, что исполняемые файлы разные.
- Выполните ту же команду, что и на первом этапе (для правильной оценки):
candle.exe Product.wxs
- Выполните почти ту же команду, что и на втором шаге:
light.exe Product.wixobj -out ProductA-1.1.msi
Обратите внимание, что это версия 1.1 вместо 1.0 (это msi с нашим обновленным кодом). Однако мы не хотим просто установить это, продолжайте читать. - Вот забавная часть, мы получаем разницу в двух MSI с помощью следующей команды:
torch.exe -p -xi ProductA-1.0.wixpdb ProductA-1.1.wixpdb -out Diff.WixMst
- Теперь мы создадим файл патча из этого (Patch.wxs будет объяснен ниже):
candle.exe Patch.wxs
- Теперь мы создадим файл WixMsp с помощью этой команды:
light.exe Patch.wixobj -out Patch.WixMsp
- А теперь самое интересное. Создайте файл MSP с помощью этой команды:
pyro.exe Patch.WixMsp -out Patch.msp -t RTM Diff.Wixmst
Теперь, если все прошло по плану, у вас должно быть два файла msi и один файл msp. Если вы установили первую версию msi (ProductA-1.0.msi) и запустили HelloWorld1.exe, вы должны увидеть сообщение «Hello World 1!». Просто для забавы (и пример), запустите оба других приложения и оставьте их работающими (я сделал остановку, чтобы они оставались открытыми). Закройте HelloWorld1.exe, так как теперь мы собираемся применить обновление для этого exe-файла, но при этом мы не затронем HelloWorld2.exe или HelloWorld3.exe. Если вы сейчас установите файл msp (Patch.msp), а затем запустите HelloWorld1.exe, вы увидите обновленное сообщение «Hello World 1! Обновлено».
Теперь для магического файла Patch.wxs:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Patch
AllowRemoval="yes"
Manufacturer="Dynamo Corp"
MoreInfoURL="http://www.dynamocorp.com/"
DisplayName="Sample Patch"
Description="Small Update Patch"
Classification="Update"
>
<Media Id="5000" Cabinet="RTM.cab">
<PatchBaseline Id="RTM"/>
</Media>
<PatchFamilyRef Id="SamplePatchFamily"/>
</Patch>
<Fragment>
<PatchFamily Id='SamplePatchFamily' Version='1.0.0' Supersede='yes'>
<ComponentRef Id="HelloWorld1Component"/>
</PatchFamily>
</Fragment>
</Wix>
Не очень много, правда? Ну, самые интересные части это:
<PatchBaseline Id="RTM"/>
- Это, если вы помните, используется в нашем создании патча MSI. «RTM» упоминается в последнем шаге выше: -t RTM
- они должны совпадать.
<ComponentRef Id="HelloWorld1Component"/>
- Это указывает патч на правильный компонент для обновления, в нашем случае HelloWorld1Component.
Если вы выполняли какие-либо поиски, приведенный выше код может показаться вам знакомым, поскольку он взят из Блог Питера Марку : WiX: Создание патча с использованием новой системы сборки патчей - Часть 3
Я также очень полагался на Блог Алекса Шевчука : От MSI до WiX, часть 8 - значительное обновление
Если вам интересно: «Вау, это много шагов, зачем кому-то делать это много шагов?», Пожалуйста, помните, что после тяжелой работы (см. Выше) вам нужно перенести это в свою процедуру интеграции. , Это правильно, интегрировать, интегрировать, интегрировать ! Как ты это делаешь? Ну, это немного больше исследований, и, возможно, сообщение в блоге? - Наверное. Чтобы получить правильную информацию, вот отличная статья о Автоматизация релизов с помощью MSBuild и установщика Windows XML .
Ух ты, я надеюсь, что ты прочитал все это (все вы двое) и многому научился. Я надеюсь, что это помогает кому-то, кроме меня.
Спасибо!