Установщик Windows удаляет версионный файл во время обновления продукта, а не снижает его - PullRequest
29 голосов
/ 19 ноября 2010

Мы используем wix для создания наших настроек. Для обновления мы используем основные обновления, как показано в этого ответа Роба Меншинга . (В более новых версиях wix вы можете использовать элемент MajorUpgrade .) Обычно это работает хорошо. Старый продукт удаляется, затем новый продукт устанавливается.

Однако, очевидно, что вышеупомянутое не полностью эквивалентно удалению старого продукта вручную и последующей установке нового продукта вручную.

Рассмотрим, например, следующий сценарий:

  • Выпущена версия 1.0 нашего продукта, содержащая версию 5.0 третьей стороны dll
  • Выпущена версия 1.1 нашего продукта, содержащая версию 5.1 той же третьей стороны DLL
  • Выпущена версия 1.2 нашего продукта с понижением до версии 5.0 третьей стороны dll, поскольку мы обнаружили, что в новой версии было больше проблем, чем решено.

Очевидно, что с логикой обновления wix, связанной выше, 3-я библиотека DLL исчезнет при обновлении с версии 1.1 до 1.2. Для его восстановления необходим ремонт.

Есть ли другой способ обновления, который подойдет для этого сценария? Я думаю, что я ищу, это логика обновления, которая позволяет понизить версию компонентов, ведя себя точно так, как если бы вы вручную удаляли старый продукт, а затем вручную устанавливали новый продукт.

Ответы [ 6 ]

7 голосов
/ 13 июня 2013

Мы также столкнулись с этой проблемой, когда более ранние версии DLL не переустанавливались при значительном обновлении.Мне показалось странным, что установщик решит, какие файлы устанавливать, основываясь на версии существующих файлов, затем полностью удалит все , но все равно только установит, какие файлы были определены для установки перед удалением старый продукт.Кажется, это может быть ошибка в установщике Windows ...

Чтобы исправить эту проблему, мы переместили действие RemoveExistingProducts над действием CostFinalize.

Я знаю, что документация на MSDN рекомендует ставить RemoveExistingProducts после InstallValidate, и я не уверен, что если поместить его перед действием InstallValidate, то будут какие-то негативные побочные эффекты для незначительных обновлений, норешили выполнить только серьезные обновления для наших продуктов, так что это решение работает для нас.

4 голосов
/ 20 ноября 2010

Такое поведение обычно связано с последовательностью RemoveExistingProducts .Если это произойдет достаточно поздно, установщик Windows обнаружит, что на компьютере установлена ​​более новая версия .dll, поэтому версия 1.2 не требует его установки.Однако, когда RemoveExistingProducts приводит к удалению .dll, ничто не возвращает его назад.

Что следует попробовать, включая изменение последовательности RemoveExistingProducts и ложь о версии .dll в пакете 1.2 (сообщить номер версиивыше плохого).Недостатком последнего является плохое влияние на ремонт или исправление, так как .dll всегда выглядит устаревшим.

1 голос
/ 29 июля 2011

Попробуйте запланировать RemoveExistingProducts раньше, сразу после InstallValidate и измените значение свойства REINSTALLMODE на amus. Таким образом, старый продукт будет полностью удален до того, как будут скопированы все файлы из нового продукта, и режим a приведет к повторной установке файлов.

0 голосов
/ 19 июня 2019

Вот мое окончательное решение, основанное на ответе @ 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>
0 голосов
/ 27 марта 2019

Спустя годы эта тема помогла мне в правильном направлении. Пример полноты с 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." />
0 голосов
/ 28 марта 2013

Это неоптимально, но я исправил ту же проблему, переименовав стороннюю dll и изменив GUID на узле компонента, связанном с ним, в файле .wxs.

...