Как сделать WIX MSI всегда удалять предыдущую версию?
У меня есть система сборки CI, создающая MSI всякий раз, когда разработчик проверяет изменения. Мы запускаем автоматические приемочные тесты на установленной MSI.
В принципе, каждая MSI - это полная установка продукта, поэтому у нас нет какого-либо управления версиями (ala Windows installer) как таковой.
Каждый MSI имеет тот же GUID продукта и GUID обновления, и тот же номер версии. но имеет другой GUID пакета (используйте '*' в wix).
Что я хочу достичь, так это то, что при запуске установщика он "удалит" любую ранее установленную версию продукта и установит новую. Все из одной MSI (у нас есть запутанный процесс установки, который отсутствует нашего контроля.. citrix и sccm, поэтому мы хотим дать им простой путь установки)
Я пробовал:
<Property Id='PREVIOUSVERSIONSINSTALLED' Secure='yes' />
<Upgrade Id='$UPGRADE_GUID'>
<UpgradeVersion Minimum='1.0.0.0'
Maximum='99.0.0.0'
Property='PREVIOUSVERSIONSINSTALLED'
IncludeMinimum='yes'
IncludeMaximum='no' />
</Upgrade>
и имеют:
<InstallExecuteSequence>
<RemoveExistingProducts After='InstallFinalize' />
</InstallExecuteSequence>
и попробовали:
<InstallExecuteSequence>
<RemoveExistingProducts After='InstallInitialize' />
</InstallExecuteSequence>
Но когда я пытаюсь установить msi из последующей сборки, я получаю:
Another version of this product is already installed. Installation of this version cannot continue.
To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel.
На самом деле я этого не делал.
Я понимаю, что я могу просто обновить атрибут Version в теге продукта, но с этим сложно справиться. Во-первых, я могу создать 20+ msi-сборки в день, так как у меня есть несколько конвейеров сборки, которые производят MSI, и я не уверен, как обрабатывать нумерацию версий таким образом, чтобы это имело смысл.
Может быть, установщик Windows просто не позволяет установить этот тип "всегда перезаписывать установленную версию"?
Ответы
Ответ 1
Итак, я нашел способ сделать это, не меняя номер версии.
Я изменяю GUID продукта с каждой сборкой, но сохраняю GUID Upgrade так же.
Мне также пришлось изменить RemoveExistingProducts до Before = 'InstallInitialize'. В противном случае он оставил только "дельта" между сборками на пути установки.
Как отмечено в Wim ниже, я могу заменить сгенерированный GUID продукта на '*'
.
Ответ 2
попробовать
<InstallExecuteSequence>
<RemoveExistingProducts After='InstallFinalize' />
</InstallExecuteSequence>
Это должно удалить любые существующие продукты после завершения установки, хотя вы можете настроить точку, в которой вы ее выполняете
см. http://mohundro.com/blog/2009/02/23/getting-started-with-wix-and-major-upgrades/
также см. принятый ответ для этого вопроса
Ответ 3
Вы можете использовать этот код для удаления старой версии и установки более новой версии:
<Product Id="*"
UpgradeCode="87795f3dc95-81f5-473e-955e-2871a5bd66a5"
Name="AppName"
Language="1033"
Version="1.0.6"
Manufacturer="Manufacturer Name">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade Schedule="afterInstallInitialize"
DowngradeErrorMessage="A later version of [ProductName] is already installed"
AllowSameVersionUpgrades="yes" />
</Product>
Ответ 4
Если код продукта и версия совпадают, код пакета отличается, вы всегда получите сообщение об ошибке установщика Windows.
Я бы настоятельно рекомендовал включить информацию о версии для ваших инсталляторов в свои сборки CI. Если вы устанавливаете и впоследствии обновляете каждую сборку, то управление версиями не так уж плохо. Относительно легко добавить это в сборку CI.