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

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

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


person Dror Helper    schedule 22.09.2008    source источник


Ответы (12)


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

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

<MajorUpgrade
    AllowDowngrades="no" DowngradeErrorMessage="!(loc.NewerVersionInstalled)"
    AllowSameVersionUpgrades="no"
    />
person Ant    schedule 26.08.2010
comment
блог Боба Арсона это дает много полезной информации. - person Dave Andersen; 26.07.2012
comment
Примечание: нигде не задокументировано, но элемент <MajorUpgrade> должен быть помещен после <Package>. В противном случае candle выдает следующую ошибку: ошибка CNDL0107: проверка схемы завершилась неудачно со следующей ошибкой в ​​строке 1, столбец 473: элемент 'Product' в пространстве имен 'schemas.microsoft.com/wix/2006/wi 'имеет недопустимый дочерний элемент' MajorUpgrade 'в пространстве имен' schemas.microsoft.com/wix/2006/wi '. Список возможных ожидаемых элементов: «Пакет» .. - person Rob W; 31.01.2013
comment
+1 Этот ответ должен получить как можно больше голосов; очень заманчиво пойти с ответом, который набирает в 5 раз больше голосов, но использует более старые подходы. - person Lynn Crumbling; 20.02.2014
comment
Хорошая точка зрения. Я добавил пример, чтобы люди не игнорировали его только потому, что у него его нет! - person Ant; 21.02.2014
comment
Просто хочу отметить, что вам не нужно указывать AllowDowngrades или AllowSameVersionUpgrades. По умолчанию они уже не работают. - person Luminous; 15.05.2015
comment
Правда. Я хотел, чтобы это было очевидно для всех, кто читает мой конкретный фрагмент кода, но, конечно же, это касается не всех! - person Ant; 20.05.2015
comment
Я изменил его на принятый ответ, так как он лучше, чем мои первоначальные выводы - person Dror Helper; 29.09.2015
comment
Надеюсь, это не воскресит старый поток, но я чувствую, что для создания новой версии можно упомянуть еще пару вещей: 1) Вам нужно увеличить одну из первых трех цифр атрибута версии продукта. 2) Измените GUID в Коде обновления продукта. 3) Поместите фактический GUID в атрибут Package Id (в отличие от рекомендуемой звездочки) и сохраните его постоянным для всех версий. WIX выдает огромное предупреждение для GUID, но в противном случае он не будет работать как обновление. - person Chris Parker; 24.12.2018
comment
Мой предыдущий комментарий неверен - игнорируйте его. То, что я описал, не жалуется при установке, не обновляется, как я думал. Поместите звездочку в поле Product Id. Поместите фактический GUID в Product UpgradeCode - и НИКОГДА не меняйте его. Поместите звездочку в Package Id. Наконец, когда вы увеличите числа в версии продукта, произойдет фактическое обновление. - person Chris Parker; 25.12.2018
comment
Пробовал и получил уже установленную другую версию этого продукта - person AriesConnolly; 15.07.2020
comment
То же, что и AriesConnolly, уже установлена ​​другая версия этого продукта ошибка - person sushi7777; 02.09.2020
comment
Насколько я понимаю, вы получаете эту ошибку, когда перекомпилировали программу установки без увеличения номера версии. Вы можете установить для атрибута AllowSameVersionUpgrades значение yes, но это имеет свои проблемы ... - person Ant; 10.09.2020

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

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

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

person Dror Helper    schedule 22.09.2008
comment
Кажется, этот вопрос намного популярнее, чем я думал - person Dror Helper; 16.02.2009
comment
да, изучение WiX похоже на попытку разгадать непонятные заклинания, которые кто-то решил, что «имеет смысл» выполнить простое действие. Вроде как UNIX. - person mmr; 25.03.2009
comment
Хм, я подозреваю, что мне не следует использовать этот конкретный GUID в Upgrade Id =, но мне придется сопоставить его с чем-то другим. Но что? - person Anthony; 07.04.2009
comment
Также вам, возможно, придется настроить UpgradeVersion Min и max - например, Если ваша текущая версия меньше 1.0 - person Anthony; 07.04.2009
comment
Кроме того, что именно делает изменение идентификатора продукта на *? Создает ли он каждый раз новый идентификатор продукта? Каковы последствия того, что у вашего продукта больше нет фиксированного идентификатора? - это звучит как излишество. - person Anthony; 07.04.2009
comment
@Anthony - да, использование * приведет к тому, что каждый раз будет генерироваться новый идентификатор продукта. Я обнаружил, что для работы автоматического обновления мне нужен новый идентификатор продукта для каждой версии, и это самый простой способ сделать это. - person Dror Helper; 07.04.2009
comment
Нам нужно знать идентификатор, поэтому генерируйте (вручную) новый идентификатор для каждого общедоступного выпуска. Использование одного и того же идентификатора для всех внутренних бета-версий. Работает нормально, но вы не можете автоматически обновляться между бета-версиями, что для нас нормально - person saschabeaumont; 07.04.2009
comment
@Antony, @Dror Helper: Я почти уверен, что вам не следует использовать * для генерации нового GUID здесь. Идентификатор GUID внутри (Upgrade Id =) должен быть жестко закодирован и исправлен, и он должен соответствовать GUID в вашем атрибуте (Product UpgradeCode =). - person Jonathan Hartley; 30.09.2009
comment
Под этим я подразумеваю, что не используйте * в идентификаторе обновления, но, конечно, используйте его в идентификаторе продукта, как задумал Dror. - person Jonathan Hartley; 30.09.2009
comment
обратите внимание, что это приведет к удалению любой установленной версии, даже если она новее, чем та, которую вы пытаетесь установить. - person Lucas; 03.12.2009
comment
Я думаю, вам, вероятно, следует отредактировать свой пример, чтобы НЕ иметь фактического GUID. Я уверен, что люди скопируют и вставят это и будут использовать дословно. Может быть, использовать ВАШ-ПРОДУКТ-UPGRADECODE-GUID-ЗДЕСЬ? - person Brown; 05.02.2010
comment
В вашем примере есть ошибка. MSI ProductVersion поддерживает только три поля версии; поэтому четвертое поле вообще не будет сравниваться. См. Примечание в разделах VersionMin и VersionMax на сайте msdn.microsoft.com /en-us/library/aa372379(VS.85).aspx - person Sridhar Ratnakumar; 26.08.2010
comment
Для wix2 идентификатор продукта должен быть "????????-????-????-????-????????????" вместо "*". - person Sridhar Ratnakumar; 26.08.2010
comment
Хотя обновление, похоже, работает с использованием описанного выше метода, в разделе «Установка и удаление программ» я все еще вижу старую версию (и, конечно же, новую). Есть идеи, почему это происходит и как я действительно могу удалить старую версию? - person Florin Sabau; 02.11.2010
comment
При использовании этой техники мне все еще нужно менять UpgradeCode между выпусками? - person Florin Sabau; 02.11.2010
comment
Это тоже помогло мне, оказалось, что ПРЕДЫДУЩИЕ УСТАНОВЛЕННЫЕ ВЕРСИИ действительно важны, хотя, похоже, ничто не использует это свойство ... - person Trejkaz; 02.06.2011
comment
Я сделал именно то, что было предложено, но у меня это не работает. Если я запустил свою новую установку, она просто проигнорирует существующую установку и установит новую копию. Что мне может не хватать? - person Jonathan; 04.08.2011
comment
Кажется, у меня нет элемента InstallExecuteSequence ... (почесывая голову). - person jpierson; 25.04.2012
comment
@jpierson Вы уверены, что размещаете InstallExecuteSequence в правильном родительском элементе? Я сделал эту ошибку уже несколько раз - person Disillusioned; 30.04.2012
comment
Почему нет элемента DontCareJustCopyTheFiles? - person ActiveTrayPrntrTagDataStrDrvr; 17.12.2013
comment
@DrorHelper Можно ли удалить (деинсталлировать) более одного продукта с помощью wix во время установки msi, созданного wix. Пожалуйста, изучите мой вопрос SO и направьте меня stackoverflow.com/questions/26863294/ - person user2725407; 16.11.2014
comment
Я не уверен, я давно не работал с WIX - я думаю, вам следует написать вопрос вместо комментария, чтобы другие пользователи могли вам помочь. - person Dror Helper; 18.11.2014
comment
Уверяю вас, @mmr, упаковка в Linux на много проще. - person Aaron C. de Bruyn; 20.09.2015
comment
Обратите внимание, что это решение не будет работать, если у установщика WIX есть несколько файлов проекта, и если вы пытаетесь собрать проект с помощью msbuild. - person Jayee; 28.07.2016

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

<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-HERE должен быть идентичным.

person Rob Mensching    schedule 07.04.2009
comment
Я читаю раздел «Обновление и исправление» в книге Ника Рамиреса о Wix здесь, и он заявляет, что если вы запланируете RemoveExistingProducts после InstallInitialize, вы также ДОЛЖНЫ запланировать <InstallExecute After="RemoveExistingProducts" />. В вашем примере этого нет - значит ли это, что книга неправильная? - person Wim Coenen; 19.11.2010
comment
Я никогда не планирую InstallExecute явно. - person Rob Mensching; 23.11.2010
comment
Из интереса, что вы делаете для мелких обновлений? - person Richard Szalay; 14.04.2011
comment
Я не. В WiX v3.6 Burn упростит выполнение незначительных обновлений, но без Burn требует ручного взаимодействия со стороны пользователя (необходимо указать параметры командной строки), что делает незначительные обновления практически бесполезными. :) - person Rob Mensching; 01.05.2011
comment
@RobMensching: как избежать установки старой версии поверх новой? Ваш ответ работает для меня (единственный пример крупного обновления, который я могу вообще скомпилировать с WiX v3.5.2519.0), но можно установить более старую версию (после этого я вижу обе версии в «Установка и удаление программ») . - person Christian Specht; 30.11.2011
comment
Хорошо, я только что нашел элемент MajorUpgrade в этот ответ, который делает именно то, что я хочу, включая предотвращение перехода на более раннюю версию. - person Christian Specht; 30.11.2011
comment
@RobMensching Можно ли удалить (удалить) более одного продукта с помощью wix во время установки msi, созданного wix. Я могу обновить предыдущую версию на новую с помощью wix, но мне нужно удалить все другие 2 приложения также во время этого обновления . Пожалуйста, ознакомьтесь с моим вопросом SO и направьте меня stackoverflow.com/questions/26863294/ - person user2725407; 16.11.2014

Элемент 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>

Обратите внимание: если вы будете осторожны со своими сборками, вы можете предотвратить случайную установку старой версии вашего продукта поверх новой. Для этого и предназначено поле «Максимум». Когда мы создаем установщики, мы устанавливаем 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

person Brian Gillespie    schedule 18.10.2008
comment
@ Брайан Гиллеспи: что значит ... если есть неизмененные файлы ... значит? По каким критериям установщик Windows решает, когда заменять файл, AssemblyVersion, AssemblyFileVersion, размер файла, ...? - person donttellya; 21.05.2014
comment
@donttellya +1 усвоил это на собственном горьком опыте. RemoveExistingProducts был запланирован после InstallFinalize, а библиотеки DLL не обновлялись, поскольку assemblyVersion не изменилась, но другие поля, такие как AssemblyProduct, остались. Я не хочу зависеть от процедуры сравнения файлов - я просто хочу, чтобы предыдущее приложение УДАЛОСЬ - person wal; 18.02.2015

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

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

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

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

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

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

person Mike Dimmick    schedule 22.09.2008
comment
Несомненно, Майк точно знает, о чем говорит, при всем уважении, но я вздыхаю от отчаяния, когда думаю о том, что у меня в голове есть твердое понимание того, что делает установщик Windows. Прежде чем я это узнаю, я буду выполнять консультации по Java и .NET для корпоративных клиентов в ужасных городах технических центров, за кольцевой дорогой, заполнять свои отчеты TPS и удивляться, почему жизнь кажется такой пустой. Я думаю, что мой следующий проект может быть установлен с помощью NSIS, который, несмотря на все его недостатки, как нелепый язык, похожий на ассемблер, не помог мне понять, что делает установщик Windows. - person Jonathan Hartley; 30.09.2009
comment
@Tartley - используйте InnoSetup, это избавит вас от ассемблерного языка :) Убедитесь, что вы тоже пользуетесь IStool, это очень помогает. Также - согласился, что для простой установки все это слишком сложно, но я думаю, что им действительно нужна эта сложность для установки чего-то вроде SQL Server 2008 ... - person Roman Starkov; 17.11.2009

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

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

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

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

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

http://web.archive.org/web/20110209022712/http://wixwiki.com/index.php?title=Main_Page

person CheGueVerra    schedule 24.09.2008
comment
Пример на странице не работает должным образом wix. tramontana.co.hu/tutorial/upgrades-and-modularization/. Я играл с этим. Можно даже перейти на более раннюю версию, если на странице указано, что это будет запрещено - person sergtk; 10.06.2012

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

person Sasha    schedule 16.12.2011

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

person Community    schedule 25.06.2009
comment
Спасибо за ссылку на эту статью ... это здорово! - person Robert P; 21.10.2009

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

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

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

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

person Daniel Morritt    schedule 24.12.2010
comment
Пакет: Тип идентификатора: Описание AutogenGuid: GUID кода пакета для продукта или модуля слияния. При компиляции продукта этот атрибут не следует устанавливать, чтобы разрешить создание кода пакета для каждой сборки. При компиляции модуля слияния этот атрибут должен быть установлен на guid модуляризации. ---- Значит, нам не нужно обращать внимание на идентификатор пакета, верно? - person Cooper.Wu; 18.10.2011
comment
Ваша ссылка мертва - person bam500; 22.02.2017

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

person Merill Fernando    schedule 09.03.2010

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

<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 в Upgrade.

person NishantJ    schedule 04.12.2015

Вот что у меня сработало даже с большой оценкой ВНИЗ:

<Wix ...>
  <Product ...>
    <Property Id="REINSTALLMODE" Value="amus" />
    <MajorUpgrade AllowDowngrades="yes" />
person Gian Marco    schedule 24.03.2014