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





Наконец, я нашел решение - я публикую его здесь для других людей, у которых может быть такая же проблема (все пятеро из вас):
Под товаром добавьте следующее:
<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
да, изучение WiX похоже на попытку разгадать непонятные заклинания, которые кто-то решил, что «имеет смысл» выполнить простое действие. Вроде как UNIX.
Хм, я подозреваю, что мне не следует использовать этот конкретный GUID в «Upgrade Id =», но мне придется сопоставить его с чем-то другим. Но что?
Также вам, возможно, придется настроить UpgradeVersion Min и max - например, Если ваша текущая версия меньше 1.0
Кроме того, что именно делает «Изменить идентификатор продукта на *»? Создает ли он каждый раз новый идентификатор продукта? Каковы последствия того, что у вашего продукта больше нет фиксированного идентификатора? - это звучит как излишество.
@Anthony - да, использование * приведет к тому, что каждый раз будет генерироваться новый идентификатор продукта. Я обнаружил, что для работы «автоматического обновления» мне нужен новый идентификатор продукта для каждой версии, и это самый простой способ сделать это.
Нам нужно знать идентификатор, поэтому генерируйте (вручную) новый идентификатор для каждого общедоступного выпуска. Использование одного идентификатора для всех внутренних бета-версий. Работает нормально, но вы не можете автоматически обновляться между бета-версиями, что для нас нормально
@Antony, @Dror Helper: Я почти уверен, что вам не следует использовать здесь «*» для генерации нового GUID. Идентификатор GUID внутри (Upgrade Id = "") должен быть жестко запрограммирован и исправлен, и он должен соответствовать идентификатору GUID в вашем атрибуте (Product UpgradeCode = "").
Под этим я подразумеваю, что не используйте "*" в идентификаторе обновления, но, конечно, используйте его в идентификаторе продукта, как задумал Dror.
обратите внимание, что это удалит установленную версию Любые, даже если она новее, чем та, которую вы пытаетесь установить.
Я думаю, вам, вероятно, следует отредактировать свой пример, чтобы НЕ иметь фактического GUID. Я уверен, что люди скопируют и вставят это и будут использовать дословно. Может быть, использовать "ВАШ-ПРОДУКТ-UPGRADECODE-GUID-ЗДЕСЬ"?
В вашем примере есть ошибка. ProductVersion от MSI поддерживает только три поля версии; поэтому четвертое поле вообще не будет сравниваться. См. Примечание под VersionMin и VersionMax в msdn.microsoft.com/en-us/library/aa372379(VS.85).aspx
Для wix2 идентификатор продукта должен быть "????????-????-????-????-????????????" вместо "*".
Хотя обновление, похоже, работает с использованием описанного выше метода, в разделе «Установка и удаление программ» я все еще вижу старую версию (и, конечно же, новую). Есть идеи, почему это происходит и как я действительно могу удалить старую версию?
При использовании этой техники мне все еще нужно менять UpgradeCode между выпусками?
Это тоже помогло мне, оказалось, что ПРЕДЫДУЩАЯ УСТАНОВЛЕННАЯ ВЕРСИЯ действительно важна, хотя, похоже, ничто не использует это свойство ...
Я сделал именно то, что было предложено, но у меня это не работает. Если я запустил свою новую установку, она просто проигнорирует существующую установку и установит новую копию. Что мне может не хватать?
Кажется, у меня нет элемента InstallExecuteSequence ... (почесывая голову).
@jpierson Вы уверены, что размещаете InstallExecuteSequence в правильном родительском элементе? Я сделал эту ошибку уже несколько раз
Почему нет элемента DontCareJustCopyTheFiles?
@DrorHelper Можно ли удалить (деинсталлировать) более одного продукта с помощью wix во время установки msi, созданного wix. Пожалуйста, ознакомьтесь с моим вопросом SO и направьте меня stackoverflow.com/questions/26863294/…
Я не уверен, я давно не работал с WIX - я думаю, вам следует написать вопрос вместо комментария, чтобы другие пользователи могли вам помочь.
Уверяю вас @mmr, упаковка в Linux на много проще.
Обратите внимание, что это решение не будет работать, если в установщике WIX есть несколько файлов проекта, и если вы пытаетесь собрать проект с помощью msbuild.
Возможно, вам лучше спросить об этом на Список рассылки 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.
@Tartley - используйте InnoSetup, это избавит вас от языка ассемблера :) Убедитесь, что вы также установили IStool, это очень помогает. Также - согласился, что для простой установки все это слишком сложно, но я думаю, что им действительно нужна эта сложность для установки чего-то вроде SQL Server 2008 ...
Я использовал этот сайт, чтобы понять основы 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/…. Я играл с этим. Можно даже перейти на более раннюю версию, если на странице указано, что это будет запрещено
Элемент 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 +1 усвоил это на собственном горьком опыте. RemoveExistingProducts был запланирован после InstallFinalize, и dll не обновлялись, поскольку assemblyVersion не изменилась, но другие поля, такие как AssemblyProduct, остались. Я не хочу зависеть от процедуры сравнения файлов - я просто хочу, чтобы предыдущее приложение УДАЛОСЬ
Вот синтаксис, который я использую для крупных обновлений:
<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" />. В вашем примере этого нет - значит ли это, что книга неправильная?
Я никогда не планирую InstallExecute явно.
Ради интереса, что вы делаете для мелких обновлений?
Я не. В WiX v3.6 Burn упростит выполнение незначительных обновлений, но без Burn требует ручного взаимодействия со стороны пользователя (необходимо указать параметры командной строки), что делает незначительные обновления практически бесполезными. :)
@RobMensching: как избежать установки старой версии поверх новой? Ваш ответ работает для меня (единственный пример "крупного обновления", который я могу вообще скомпилировать с WiX v3.5.2519.0), но можно установить более старую версию (после этого я вижу обе версии в "Добавить / Удаление программ »).
Хорошо, я только что нашел Элемент MajorUpgrade в этот ответ, который делает именно то, что я хочу, включая предотвращение перехода на более раннюю версию.
@RobMensching Можно ли удалить (удалить) более одного продукта с помощью wix во время установки msi, созданного wix. Я могу обновить предыдущую версию на новую с помощью wix, но мне нужно удалить все другие 2 приложения также во время этого обновления . Пожалуйста, ознакомьтесь с моим вопросом SO и направьте меня stackoverflow.com/questions/26863294/…
Предлагаю взглянуть на самоучитель Алекса Шевчука. Он объясняет «серьезное обновление» через WiX на хорошем практическом примере в От MSI к WiX, часть 8 - серьезное обновление.
Спасибо за ссылку на эту статью ... это здорово!
Я использую последнюю версию 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"
/>
Сообщение блога Боба Арсона об этом дает много полезной информации.
Примечание: нигде не задокументировано, но элемент «<MajorUpgrade>» должен быть размещен после<Package>. В противном случае candle выдает следующую ошибку: «ошибка CNDL0107: проверка схемы завершилась неудачно со следующей ошибкой в строке 1, столбец 473: элемент« Продукт »в пространстве имен« schemas.microsoft.com/wix/2006/wi »имеет недопустимый дочерний элемент« MajorUpgrade »в пространстве имен« schemas.microsoft.com/wix/2006/wi ». Список из возможных ожидаемых элементов: 'Package'. ".
+1 Этот ответ должен получить как можно больше голосов; очень заманчиво пойти с ответом, который имеет в 5 раз больше голосов, но использует более старые подходы.
Хорошая точка зрения. Я добавил пример, чтобы люди не игнорировали его только потому, что у него его нет!
Просто хочу отметить, что вам не нужно указывать AllowDowngrades или AllowSameVersionUpgrades. По умолчанию они уже не работают.
Истинный. Я хотел, чтобы это было очевидно для всех, кто читает мой конкретный фрагмент кода, но, конечно же, это касается не всех!
Я изменил его на принятый ответ, так как он лучше, чем мои первоначальные выводы
Надеюсь, это не воскресит старую ветку, но я чувствую, что для создания «более новой» версии можно упомянуть еще пару вещей: 1) Вам нужно увеличить одну из первых трех цифр атрибута «Версия продукта». 2) Измените GUID в «Коде обновления продукта». 3) Поместите фактический GUID в атрибут «Package Id» (в отличие от рекомендуемой звездочки) и сохраните его постоянным во всех версиях. WIX выдает огромное предупреждение для GUID, но в противном случае он не будет работать как обновление.
Мой предыдущий комментарий неверен - игнорируйте его. То, что я описал, не жалуется при установке, не обновляется, как я думал. Поставьте звездочку в поле «Идентификатор продукта». Поместите фактический GUID в "Product UpgradeCode" - и НИКОГДА не меняйте его. Поставьте звездочку в поле «Идентификатор пакета». Наконец, когда вы увеличите числа в «Версии продукта», произойдет фактическое обновление.
Попробовал и получил "уже установлена другая версия этого продукта"
То же, что и AriesConnolly, уже установлена другая версия этого продукта ошибка
Насколько я понимаю, вы получаете эту ошибку, когда перекомпилировали программу установки без увеличения номера версии. Вы можете установить атрибут AllowSameVersionUpgrades на yes, но это имеет свои проблемы ...
Одна важная вещь, которую я некоторое время упускал из руководств (украдено из http://www.tramontana.co.hu/wix/lesson4.php), что приводило к ошибке «Другая версия этого продукта уже установлена»:
* Небольшие обновленияозначают небольшие изменения в одном или нескольких файлах, при этом изменение не требует изменения версии продукта (major.minor.build). Вам также не нужно менять GUID продукта. Обратите внимание, что вам всегда нужно изменять GUID пакета при создании нового файла .msi, который во всех отношениях отличается от предыдущих. Установщик отслеживает установленные вами программы и находит их, когда пользователь хочет изменить или удалить установку, используя эти GUID. Использование одного и того же GUID для разных пакетов запутает установщик.
Незначительные улучшенияобозначают изменения, при которых версия продукта уже изменится. Измените атрибут версии тега продукта. Продукт останется прежним, поэтому вам не нужно менять GUID продукта, но, конечно же, получите новый GUID пакета.
Основные обновленияобозначают значительные изменения, такие как переход от одной полной версии к другой. Измените все: атрибут версии, GUID продукта и пакета.
Пакет: Тип идентификатора: Описание AutogenGuid: GUID кода пакета для продукта или модуля слияния. При компиляции продукта этот атрибут не следует устанавливать, чтобы разрешить создание кода пакета для каждой сборки. При компиляции модуля слияния этот атрибут должен быть установлен на guid модуляризации. ---- Значит, нам не нужно обращать внимание на идентификатор пакета, верно?
Ваша ссылка мертва
Я читал документацию 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.
Кажется, этот вопрос намного популярнее, чем я думал