Как реализовать обновление установщика WiX? - PullRequest
227 голосов
/ 22 сентября 2008

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

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

Ответы [ 12 ]

216 голосов
/ 22 сентября 2008

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

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

    <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 add:

    <RemoveExistingProducts Before="InstallInitialize" /> 
    

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

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

178 голосов
/ 26 августа 2010

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

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

<MajorUpgrade
    AllowDowngrades="no" DowngradeErrorMessage="!(loc.NewerVersionInstalled)"
    AllowSameVersionUpgrades="no"
    />
88 голосов
/ 07 апреля 2009

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

<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, существуют другие места для планирования удаления продуктов в зависимости от желаемой оптимизации. Обратите внимание, что PUT-GUID-HERE должен быть идентичен.

40 голосов
/ 18 октября 2008

Элемент Upgrade внутри элемента Product в сочетании с правильным планированием действия выполнит удаление, которое вы после. Не забудьте перечислить коды обновления всех продуктов, которые вы хотите удалить.

<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>

Обратите внимание, что, если вы будете осторожны с вашими сборками, вы можете предотвратить случайную установку более старой версии вашего продукта поверх новой. Вот для чего используется поле Maximum. При сборке установщиков мы устанавливаем 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

15 голосов
/ 22 сентября 2008

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

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

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

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

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

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

11 голосов
/ 24 сентября 2008

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

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

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

И как сказал Майк в книге от Apress «Полное руководство по установщику Windows», он поможет вам разобраться, но он написан не с использованием WiX.

Вот еще один очень полезный сайт:

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

10 голосов
/ 16 декабря 2011

Я прочитал документацию 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 " для небольших и малых обновлений, но это не говорит эти параметры ЗАПРЕЩЕНЫ для крупных обновлений - они просто перестают работать. Так что не стоит использовать их с серьезными обновлениями.

7 голосов
/ 24 декабря 2010

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

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

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

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

7 голосов
/ 25 июня 2009

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

5 голосов
/ 09 марта 2010

Я использую последнюю версию 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 Продукта.

...