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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
235
0
124 748
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

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

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

    <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

Кажется, этот вопрос намного популярнее, чем я думал

Dror Helper 16.02.2009 16:50

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

mmr 25.03.2009 03:44

Хм, я подозреваю, что мне не следует использовать этот конкретный GUID в «Upgrade Id =», но мне придется сопоставить его с чем-то другим. Но что?

Anthony 07.04.2009 01:27

Также вам, возможно, придется настроить UpgradeVersion Min и max - например, Если ваша текущая версия меньше 1.0

Anthony 07.04.2009 01:29

Кроме того, что именно делает «Изменить идентификатор продукта на *»? Создает ли он каждый раз новый идентификатор продукта? Каковы последствия того, что у вашего продукта больше нет фиксированного идентификатора? - это звучит как излишество.

Anthony 07.04.2009 12:58

@Anthony - да, использование * приведет к тому, что каждый раз будет генерироваться новый идентификатор продукта. Я обнаружил, что для работы «автоматического обновления» мне нужен новый идентификатор продукта для каждой версии, и это самый простой способ сделать это.

Dror Helper 07.04.2009 14:50

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

saschabeaumont 07.04.2009 14:56

@Antony, @Dror Helper: Я почти уверен, что вам не следует использовать здесь «*» для генерации нового GUID. Идентификатор GUID внутри (Upgrade Id = "") должен быть жестко запрограммирован и исправлен, и он должен соответствовать идентификатору GUID в вашем атрибуте (Product UpgradeCode = "").

Jonathan Hartley 30.09.2009 15:32

Под этим я подразумеваю, что не используйте "*" в идентификаторе обновления, но, конечно, используйте его в идентификаторе продукта, как задумал Dror.

Jonathan Hartley 30.09.2009 16:39

обратите внимание, что это удалит установленную версию Любые, даже если она новее, чем та, которую вы пытаетесь установить.

Lucas 03.12.2009 00:38

Я думаю, вам, вероятно, следует отредактировать свой пример, чтобы НЕ иметь фактического GUID. Я уверен, что люди скопируют и вставят это и будут использовать дословно. Может быть, использовать "ВАШ-ПРОДУКТ-UPGRADECODE-GUID-ЗДЕСЬ"?

Brown 05.02.2010 22:54

В вашем примере есть ошибка. ProductVersion от MSI поддерживает только три поля версии; поэтому четвертое поле вообще не будет сравниваться. См. Примечание под VersionMin и VersionMax в msdn.microsoft.com/en-us/library/aa372379(VS.85).aspx

Sridhar Ratnakumar 26.08.2010 22:50

Для wix2 идентификатор продукта должен быть "????????-????-????-????-????????????" вместо "*".

Sridhar Ratnakumar 26.08.2010 23:09

Хотя обновление, похоже, работает с использованием описанного выше метода, в разделе «Установка и удаление программ» я все еще вижу старую версию (и, конечно же, новую). Есть идеи, почему это происходит и как я действительно могу удалить старую версию?

Florin Sabau 02.11.2010 11:58

При использовании этой техники мне все еще нужно менять UpgradeCode между выпусками?

Florin Sabau 02.11.2010 12:05

Это тоже помогло мне, оказалось, что ПРЕДЫДУЩАЯ УСТАНОВЛЕННАЯ ВЕРСИЯ действительно важна, хотя, похоже, ничто не использует это свойство ...

Trejkaz 02.06.2011 09:57

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

Jonathan 04.08.2011 10:01

Кажется, у меня нет элемента InstallExecuteSequence ... (почесывая голову).

jpierson 25.04.2012 00:40

@jpierson Вы уверены, что размещаете InstallExecuteSequence в правильном родительском элементе? Я сделал эту ошибку уже несколько раз

Disillusioned 30.04.2012 16:22

Почему нет элемента DontCareJustCopyTheFiles?

ActiveTrayPrntrTagDataStrDrvr 17.12.2013 19:56

@DrorHelper Можно ли удалить (деинсталлировать) более одного продукта с помощью wix во время установки msi, созданного wix. Пожалуйста, ознакомьтесь с моим вопросом SO и направьте меня stackoverflow.com/questions/26863294/…

user2725407 16.11.2014 17:53

Я не уверен, я давно не работал с WIX - я думаю, вам следует написать вопрос вместо комментария, чтобы другие пользователи могли вам помочь.

Dror Helper 18.11.2014 10:11

Уверяю вас @mmr, упаковка в Linux на много проще.

Aaron C. de Bruyn 20.09.2015 21:36

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

Jayee 28.07.2016 09:27

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

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

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

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

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

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

Несомненно, Майк точно знает, о чем говорит, при всем уважении, но я вздыхаю от отчаяния, когда думаю о том, что у меня в голове есть твердое понимание того, что делает установщик Windows. Прежде чем я это узнаю, я буду выполнять работу по консультированию по Java и .NET для корпоративных клиентов в ужасных городах технических центров, за кольцевой дорогой, заполнять свои отчеты TPS и удивляться, почему жизнь кажется такой пустой. Я думаю, что мой следующий проект может быть установлен с помощью NSIS, который, несмотря на все его недостатки, как нелепый язык, похожий на ассемблер, не помог мне понять, что делает установщик Windows.

Jonathan Hartley 30.09.2009 16:54

@Tartley - используйте InnoSetup, это избавит вас от языка ассемблера :) Убедитесь, что вы также установили IStool, это очень помогает. Также - согласился, что для простой установки все это слишком сложно, но я думаю, что им действительно нужна эта сложность для установки чего-то вроде SQL Server 2008 ...

Roman Starkov 17.11.2009 13:32

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

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

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

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

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

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

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

sergtk 10.06.2012 05:49

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

@ Брайан Гиллеспи: что означает "... если есть неизмененные файлы ..."? По каким критериям установщик Windows решает, когда заменять файл, AssemblyVersion, AssemblyFileVersion, размер файла, ...?

donttellya 21.05.2014 13:01

@donttellya +1 усвоил это на собственном горьком опыте. RemoveExistingProducts был запланирован после InstallFinalize, и dll не обновлялись, поскольку assemblyVersion не изменилась, но другие поля, такие как AssemblyProduct, остались. Я не хочу зависеть от процедуры сравнения файлов - я просто хочу, чтобы предыдущее приложение УДАЛОСЬ

wal 18.02.2015 04:25

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

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

Я читаю раздел «Обновление и исправление» в книге Ника Рамиреса о Wix здесь, и он заявляет, что если вы планируете RemoveExistingProducts после InstallInitialize, вы ДОЛЖНЫ также запланировать <InstallExecute After = "RemoveExistingProducts" />. В вашем примере этого нет - значит ли это, что книга неправильная?

Wim Coenen 19.11.2010 17:50

Я никогда не планирую InstallExecute явно.

Rob Mensching 23.11.2010 06:43

Ради интереса, что вы делаете для мелких обновлений?

Richard Szalay 14.04.2011 21:36

Я не. В WiX v3.6 Burn упростит выполнение незначительных обновлений, но без Burn требует ручного взаимодействия со стороны пользователя (необходимо указать параметры командной строки), что делает незначительные обновления практически бесполезными. :)

Rob Mensching 01.05.2011 19:47

@RobMensching: как избежать установки старой версии поверх новой? Ваш ответ работает для меня (единственный пример "крупного обновления", который я могу вообще скомпилировать с WiX v3.5.2519.0), но можно установить более старую версию (после этого я вижу обе версии в "Добавить / Удаление программ »).

Christian Specht 30.11.2011 01:47

Хорошо, я только что нашел Элемент MajorUpgrade в этот ответ, который делает именно то, что я хочу, включая предотвращение перехода на более раннюю версию.

Christian Specht 30.11.2011 02:08

@RobMensching Можно ли удалить (удалить) более одного продукта с помощью wix во время установки msi, созданного wix. Я могу обновить предыдущую версию на новую с помощью wix, но мне нужно удалить все другие 2 приложения также во время этого обновления . Пожалуйста, ознакомьтесь с моим вопросом SO и направьте меня stackoverflow.com/questions/26863294/…

user2725407 16.11.2014 18:00

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

Спасибо за ссылку на эту статью ... это здорово!

Robert P 21.10.2009 23:01

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

Ответ принят как подходящий

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

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

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

Сообщение блога Боба Арсона об этом дает много полезной информации.

Dave Andersen 26.07.2012 22:15

Примечание: нигде не задокументировано, но элемент «<MajorUpgrade>» должен быть размещен после<Package>. В противном случае candle выдает следующую ошибку: «ошибка CNDL0107: проверка схемы завершилась неудачно со следующей ошибкой в ​​строке 1, столбец 473: элемент« Продукт »в пространстве имен« schemas.microsoft.com/wix/2006/wi »имеет недопустимый дочерний элемент« MajorUpgrade »в пространстве имен« schemas.microsoft.com/wix/2006/wi ». Список из возможных ожидаемых элементов: 'Package'. ".

Rob W 31.01.2013 15:39

+1 Этот ответ должен получить как можно больше голосов; очень заманчиво пойти с ответом, который имеет в 5 раз больше голосов, но использует более старые подходы.

Lynn Crumbling 20.02.2014 20:59

Хорошая точка зрения. Я добавил пример, чтобы люди не игнорировали его только потому, что у него его нет!

Ant 21.02.2014 17:22

Просто хочу отметить, что вам не нужно указывать AllowDowngrades или AllowSameVersionUpgrades. По умолчанию они уже не работают.

Luminous 15.05.2015 17:17

Истинный. Я хотел, чтобы это было очевидно для всех, кто читает мой конкретный фрагмент кода, но, конечно же, это касается не всех!

Ant 20.05.2015 10:22

Я изменил его на принятый ответ, так как он лучше, чем мои первоначальные выводы

Dror Helper 29.09.2015 12:59

Надеюсь, это не воскресит старую ветку, но я чувствую, что для создания «более новой» версии можно упомянуть еще пару вещей: 1) Вам нужно увеличить одну из первых трех цифр атрибута «Версия продукта». 2) Измените GUID в «Коде обновления продукта». 3) Поместите фактический GUID в атрибут «Package Id» (в отличие от рекомендуемой звездочки) и сохраните его постоянным во всех версиях. WIX выдает огромное предупреждение для GUID, но в противном случае он не будет работать как обновление.

Chris Parker 24.12.2018 22:46

Мой предыдущий комментарий неверен - игнорируйте его. То, что я описал, не жалуется при установке, не обновляется, как я думал. Поставьте звездочку в поле «Идентификатор продукта». Поместите фактический GUID в "Product UpgradeCode" - и НИКОГДА не меняйте его. Поставьте звездочку в поле «Идентификатор пакета». Наконец, когда вы увеличите числа в «Версии продукта», произойдет фактическое обновление.

Chris Parker 25.12.2018 00:57

Попробовал и получил "уже установлена ​​другая версия этого продукта"

AriesConnolly 15.07.2020 15:16

То же, что и AriesConnolly, уже установлена ​​другая версия этого продукта ошибка

sushi7777 02.09.2020 16:12

Насколько я понимаю, вы получаете эту ошибку, когда перекомпилировали программу установки без увеличения номера версии. Вы можете установить атрибут AllowSameVersionUpgrades на yes, но это имеет свои проблемы ...

Ant 10.09.2020 14:16

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

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

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

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

Пакет: Тип идентификатора: Описание AutogenGuid: GUID кода пакета для продукта или модуля слияния. При компиляции продукта этот атрибут не следует устанавливать, чтобы разрешить создание кода пакета для каждой сборки. При компиляции модуля слияния этот атрибут должен быть установлен на guid модуляризации. ---- Значит, нам не нужно обращать внимание на идентификатор пакета, верно?

Cooper.Wu 18.10.2011 08:27

Ваша ссылка мертва

bam500 22.02.2017 18:30

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

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

Но проблема основная причина заключалась в том, что в документации говорится об использовании параметров «ПЕРЕУСТАНОВИТЬ = ВСЕ РЕЖИМ ПЕРЕУСТАНОВКИ = vomus» для мелких и небольших обновлений, но не говорится, что эти параметры являются ЗАПРЕЩЕНО для крупных обновлений - они просто перестают работать. Так что не стоит использовать их с серьезными обновлениями.

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

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

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

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

Другие вопросы по теме