Как реализовать обновление установщика WiX?

На работе мы используем WiX для создания пакетов установки. Мы хотим, чтобы установка продукта X привела к удалению предыдущей версии этого продукта на этом компьютере.

Я прочитал несколько мест в Интернете о серьезном обновлении, но не смог заставить его работать. Может ли кто-нибудь указать конкретные шаги, которые мне нужно предпринять, чтобы добавить функцию удаления предыдущей версии в WiX?

Ответ 1

В новейших версиях (из бета-версии 3.5.1315.0) вы можете использовать элемент MajorUpgrade вместо использования ваш собственный.

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

<MajorUpgrade
    AllowDowngrades="no" DowngradeErrorMessage="!(loc.NewerVersionInstalled)"
    AllowSameVersionUpgrades="no"
    />

Ответ 2

Наконец, я нашел решение - я размещаю его здесь для других людей, у которых может быть одна и та же проблема (все пять из вас):

  • Измените идентификатор продукта на *
  • В приложении добавить следующее:

    <Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
    <Upgrade Id="YOUR_GUID">  
       <UpgradeVersion
          Minimum="1.0.0.0" Maximum="99.0.0.0"
          Property="PREVIOUSVERSIONSINSTALLED"
          IncludeMinimum="yes" IncludeMaximum="no" />
    </Upgrade> 
    
  • В разделе InstallExecuteSequence добавьте:

    <RemoveExistingProducts Before="InstallInitialize" /> 
    

Теперь, когда я устанавливаю продукт, он удаляет предыдущие установленные версии.

Примечание. замените идентификатор обновления собственным GUID

Ответ 3

Ниже приведен тип синтаксиса, который я использую для основных обновлений:

<Product Id="*" UpgradeCode="PUT-GUID-HERE" Version="$(var.ProductVersion)">
 <Upgrade Id="PUT-GUID-HERE">
    <UpgradeVersion OnlyDetect="yes" Minimum="$(var.ProductVersion)" Property="NEWERVERSIONDETECTED" IncludeMinimum="no" />
    <UpgradeVersion OnlyDetect="no" Maximum="$(var.ProductVersion)" Property="OLDERVERSIONBEINGUPGRADED" IncludeMaximum="no" />
</Upgrade>

<InstallExecuteSequence>
    <RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>

Поскольку @Brian Gillespie отметил, что есть другие места для планирования RemoveExistingProducts в зависимости от желаемой оптимизации. Обратите внимание, что PUT-GUID-ЗДЕСЬ должен быть идентичным.

Ответ 4

Элемент "Обновление" внутри элемента "Продукт", в сочетании с надлежащим планированием действия, выполнит удаление, которое вы выполните. Обязательно укажите коды обновления всех продуктов, которые вы хотите удалить.

<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<Upgrade Id="00000000-0000-0000-0000-000000000000">
  <UpgradeVersion Minimum="1.0.0.0" Maximum="1.0.5.0" Property="PREVIOUSVERSIONSINSTALLED" IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>

Обратите внимание, что если вы будете осторожны с вашими сборками, вы можете помешать людям случайно установить более старую версию вашего продукта на более новую. Это поле Максимальное. Когда мы создаем инсталляторы, мы устанавливаем UpgradeVersion Maximum в построенную версию, но IncludeMaximum = "no", чтобы предотвратить этот сценарий.

У вас есть выбор в отношении планирования RemoveExistingProducts. Я предпочитаю планировать его после InstallFinalize (а не после InstallInitialize, как рекомендовали другие):

<InstallExecuteSequence>
  <RemoveExistingProducts After="InstallFinalize"></RemoveExistingProducts>
</InstallExecuteSequence>

Это приведет к тому, что предыдущая версия продукта будет установлена ​​до тех пор, пока не будут скопированы новые файлы и ключи реестра. Это позволяет мне перенести данные из старой версии в новую (например, вы переключили хранение пользовательских настроек из реестра в файл XML, но хотите быть вежливыми и перенести их настройки). Эта миграция выполняется в отложенном пользовательском действии непосредственно перед InstallFinalize.

Другим преимуществом является эффективность: если есть неизменные файлы, установщик Windows не требует повторного копирования их при планировании после InstallFinalize. Если вы планируете после InstallInitialize, предыдущая версия полностью удаляется сначала, а затем устанавливается новая версия. Это приводит к ненужному удалению и повторному копированию файлов.

Другие параметры планирования см. в разделе справки RemoveExistingProducts в MSDN. На этой неделе ссылка: http://msdn.microsoft.com/en-us/library/aa371197.aspx

Ответ 5

Возможно, вам лучше спросить об этом в списке рассылки WiX-пользователей.

WiX лучше всего использовать с четким пониманием того, что делает установщик Windows. Вы можете получить " Полное руководство по установщику Windows ".

Действие, которое удаляет существующий продукт, - это действие RemoveExistingProducts. Поскольку последствия того, что он делает, зависят от того, на что он запланирован, а именно от того, приведет ли сбой к переустановке старого продукта и повторному копированию неизмененных файлов, вы должны запланировать его самостоятельно.

RemoveExistingProducts обрабатывает элементы <Upgrade> в текущей установке, сопоставляя атрибут @Id с UpgradeCode (указанным в элементе <Product>) всех установленных продуктов в системе. UpgradeCode определяет семейство связанных продуктов. Любые продукты, имеющие этот код UpgradeCode, версии которого попадают в указанный диапазон, а UpgradeVersion/@OnlyDetect no (или отсутствует), будут удалены.

Документация RemoveExistingProducts упоминает установки UPGRADINGPRODUCTCODE собственности. Это означает, что процесс удаления удаляемого продукта получает это свойство, значением которого является Product/@Id для устанавливаемого продукта.

Если в вашей первоначальной установке не было UpgradeCode, вы не сможете использовать эту функцию.

Ответ 6

Я использовал этот сайт, чтобы помочь мне понять основы обновления WiX:

http://wix.tramontana.co.hu/tutorial/upgrades-and-modularization

Затем я создал образец установщика (установил тестовый файл), затем создал установщик Upgrade (установил 2 образца тестовых файлов). Это даст вам общее представление о том, как работает механизм.

И как сказал Майк в книге из "Apress" "Окончательное руководство к установщику Windows", это поможет вам понять, но это не написано с использованием WiX.

Еще один полезный сайт:

http://www.wixwiki.com/index.php?title=Main_Page

Ответ 7

Я прочитал документацию по WiX, скачал примеры, но у меня все еще было много проблем с обновлениями. Незначительные обновления не выполняют удаление предыдущих продуктов, несмотря на возможность указать их удаление. Я потратил больше одного дня на расследования и обнаружил, что WiX 3.5 ввел новый тег для обновлений. Вот использование:

<MajorUpgrade Schedule="afterInstallInitialize"
        DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit." 
        AllowDowngrades="no" />

Но главная причина проблем заключалась в том, что в документации сказано использовать параметры " REINSTALL = ALL REINSTALLMODE = vomus " для небольших и малых обновлений, но при этом не говорится, что эти параметры ЗАПРЕЩЕНЫ для крупных обновлений - они просто перестают работать. Таким образом, вы не должны использовать их с серьезными обновлениями.

Ответ 8

Я бы посоветовал взглянуть на учебник Алекса Шевчука. Он объясняет "серьезную модернизацию" через WiX с хорошим практическим примером в От MSI до WiX, часть 8 - Major Upgrade.

Ответ 9

Одна важная вещь, которую я упустил из учебников на некоторое время (украден из http://www.tramontana.co.hu/wix/lesson4.php), в результате чего были исправлены ошибки "Другая версия этого продукта"

* Небольшие обновления означают небольшие изменения в одном или нескольких файлах, где изменение не гарантирует изменения версии продукта (major.minor.build). Вам также не нужно менять GUID продукта. Обратите внимание, что вам всегда нужно менять GUID пакета при создании нового .msi файла, который в любом случае отличается от предыдущих. Установщик отслеживает ваши установленные программы и находит их, когда пользователь хочет изменить или удалить установку с помощью этих GUID. Использование одного и того же GUID для разных пакетов приведет к запутыванию установщика.

Незначительные обновления обозначают изменения, в которых версия продукта уже изменится. Измените атрибут Version тега Product. Продукт останется прежним, поэтому вам не нужно менять GUID продукта, но, конечно же, получить новый GUID пакета.

Основные обновления означают значительные изменения, например, переход от одной полной версии к другой. Изменить все: атрибут версии, GUID продукта и пакета.

Ответ 10

Я использую последнюю версию WiX (3.0) и не могу получить вышеописанную работу. Но это сработало:

<Product Id="*" UpgradeCode="PUT-GUID-HERE" ... >

<Upgrade Id="PUT-GUID-HERE">
  <UpgradeVersion OnlyDetect="no" Property="PREVIOUSFOUND"
     Minimum="1.0.0.0"  IncludeMinimum="yes"
     Maximum="99.0.0.0" IncludeMaximum="no" />
</Upgrade>

Обратите внимание, что PUT-GUID-HERE должен совпадать с GUID, который вы определили в свойстве UpgradeCode продукта.

Ответ 11

Ниже работал у меня.

<Product Id="*" Name="XXXInstaller" Language="1033" Version="1.0.0.0" 
    Manufacturer="XXXX" UpgradeCode="YOUR_GUID_HERE">
<Package InstallerVersion="xxx" Compressed="yes"/>
<Upgrade Id="YOUR_GUID_HERE">
    <UpgradeVersion Property="REMOVINGTHEOLDVERSION" Minimum="1.0.0.0" 
        RemoveFeatures="ALL" />
</Upgrade>
<InstallExecuteSequence>
    <RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>

Пожалуйста, убедитесь, что UpgradeCode в продукте соответствует Id в обновлении.

Ответ 12

Это то, что сработало для меня, даже с основным классом DOWN:

<Wix ...>
  <Product ...>
    <Property Id="REINSTALLMODE" Value="amus" />
    <MajorUpgrade AllowDowngrades="yes" />