Установщик Windows удаляет версионный файл во время обновления продукта, а не снижает его
Мы используем wix для создания наших настроек. For upgrading, we use major upgrades as demonstrated in this answer by Rob Mensching. (In newer wix versions you can use the MajorUpgrade element.) This normally works well. The old product is removed, then the new product is installed.
However, apparently the above is not completely equivalent to manually uninstalling the old product and then manually installing the new product.
Consider for example the following scenario:
- version 1.0 of our product is released, containing version 5.0 of a thirdparty dll
- version 1.1 of our product is released, containing version 5.1 of the same thirdparty dll
- Выпущена версия 1.2 нашего продукта, снова пониженная до версии 5.0 третьей стороны, потому что мы обнаружили, что в новой версии было больше проблем, чем решено.
Очевидно, что с логикой обновления wix, связанной выше, dll 3-его части исчезнет при обновлении с версии 1.1 до 1.2. Ремонт необходим для его восстановления.
Есть ли другой способ обновления, который будет работать для этого сценария? Я думаю, что я ищу, это логика обновления, которая позволяет понизить версию компонентов, ведя себя точно так, как если бы вы вручную удаляли старый продукт, а затем вручную устанавливали новый продукт.
4 ответа
Мы также столкнулись с этой проблемой, когда более ранние версии DLL не переустанавливались при серьезном обновлении. Мне показалось странным, что установщик решит, какие файлы устанавливать, основываясь на версии существующих файлов, затем полностью удалит все, но все равно только установит, какие файлы были определены для установки, перед удалением старого продукта. Кажется, это может быть ошибка в установщике Windows...
Чтобы исправить эту проблему, мы переместили RemoveExistingProducts
действие над CostFinalize
действие.
Я знаю, что документация по MSDN рекомендует разместить RemoveExistingProducts
после InstallValidate
и я не уверен, если поставить его перед InstallValidate
действие имеет любые негативные побочные эффекты для незначительных обновлений, но мы решили выполнить только серьезные обновления для наших продуктов, поэтому это решение, похоже, работает для нас.
Поведение, подобное этому, обычно связано с упорядочением RemoveExistingProducts. Если это произойдет достаточно поздно, установщик Windows обнаружит, что на компьютере установлена более новая версия.dll, поэтому версия 1.2 не требует его установки. Однако, когда RemoveExistingProducts приводит к удалению.dll, ничто не возвращает его обратно.
Вещи, которые нужно попробовать, включая изменение последовательности удаления RemoveExistingProducts и ложь о версии.dll в вашем пакете 1.2 (сообщите номер версии выше, чем у плохой). Недостатком последнего является плохое влияние на ремонт или исправления, так как.dll всегда выглядит устаревшим.
Попробуйте запланировать RemoveExistingProducts
раньше, сразу после InstallValidate
и измените значение REINSTALLMODE
собственность на amus
, Таким образом, старый продукт будет полностью удален перед копированием любых файлов из нового продукта, и a
Режим принудительно переустановит файлы.
Это неоптимально, но я исправил ту же проблему, переименовав стороннюю dll и изменив GUID на узле компонента, связанном с ним, в файле.wxs.
Спустя годы эта тема помогла мне в правильном направлении. Пример для полноты с RemoveExisitingProducts
переехал до калькуляции:
<Upgrade Id="UPGRADE-GUID-HERE">
<UpgradeVersion OnlyDetect="no" Property="UPGRADABLEFOUND"
Maximum="$(var.ProductVersion)" IncludeMaximum="yes" />
<UpgradeVersion OnlyDetect="yes" Property="NEWERFOUND"
Minimum="$(var.ProductVersion)" IncludeMinimum="no" />
</Upgrade>
<InstallExecuteSequence>
<Custom Action="NoDowngrade" After="FindRelatedProducts">NEWERFOUND</Custom>
<RemoveExistingProducts Before="CostInitialize" />
</InstallExecuteSequence>
<CustomAction Id="NoDowngrade" Error="A newer version of $(var.ProductName) is already installed." />
Вот мое окончательное решение, основанное на ответе @Spacemani.
Он создает записи таблицы MSI (Upgrade, LaunchCondition и т. Д.), Подобные этому
<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeErrorMessage)" />
но дает вам полный контроль над InstallExecuteSequence.
<!-- Product upgrade -->
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion OnlyDetect="no" Property="WIX_UPGRADE_DETECTED"
Maximum="$(var.ProductVersion)" IncludeMaximum="no" IncludeMinimum="no"
MigrateFeatures="yes" />
<UpgradeVersion OnlyDetect="yes" Property="WIX_DOWNGRADE_DETECTED"
Minimum="$(var.ProductVersion)" IncludeMinimum="no" />
</Upgrade>
<InstallExecuteSequence>
<RemoveExistingProducts Before="CostInitialize" />
</InstallExecuteSequence>
<Condition Message="!(loc.DowngradeErrorMessage)">NOT WIX_DOWNGRADE_DETECTED</Condition>
Обратите внимание, что вам нужно подавить ошибки ICE27 в вашем файле.wixproj следующим образом.
<PropertyGroup>
<SuppressIces>ICE27</SuppressIces>
</PropertyGroup>