Обновление Wix Tools использует старые пользовательские действия

Мы обнаружили странное поведение при использовании WIX Setup Tools. Мы развернули несколько основных версий (от 2.2.0 до 2.2.4). Для 2.2.5 мы изменили небольшие вещи в пользовательских действиях (раньше мы использовали XCOPY, теперь мы используем RoboCopy, потому что здесь есть команда "MOVE", а не только копия).

Но когда мы теперь обновляем с 2.2.4 до 2.2.5, программа установки все еще использует старую команду Copy вместо новой команды MOVE, но этого не может быть, потому что 2.2.5 не имеет никакой команды Copy. Если я разверну 2.2.6 (идентично 2.2.5) и обновлюсь с 2.2.5, он использует новый процесс обновления... Похоже, что обновление использует старый MSI.

Нашел это на ТАК

Есть ли способ предотвратить такое поведение? Это полностью нарушает процесс обновления, поскольку существующие файлы конфигурации не копируются правильно при обновлении.

Мы не можем заставить клиента очистить реестр или удалить кеш форм MSI-файлов по GUID...

Любая помощь приветствуется. заранее спасибо

ОБНОВЛЕНИЕ: новое пользовательское действие в Product.wxs

<Property Id="C_TEMP" Value="C:\Temp" />
      <Property Id="ROBOCOPY_EXE">robocopy.exe</Property>
      <CustomAction Id="CopyToTemp" Property="ROBOCOPY_EXE" Return="ignore" ExeCommand='"[INSTALLDIR]\Configuration" "[C_TEMP]\ServerSettings" ServerSettings.json' />
      <CustomAction Id="CopyFromTemp" Property="ROBOCOPY_EXE" Return="ignore" ExeCommand='"[C_TEMP]\ServerSettings" "[INSTALLDIR]\Configuration" ServerSettings.json /MOVE /IS' />

Старое таможенное действие

<Property Id="C_TEMP" Value="C:\Temp" />
  <Property Id="XCOPY_EXE">xcopy.exe</Property>
  <CustomAction Id="CopyToTemp" Property="XCOPY_EXE" Return="ignore" ExeCommand='"[INSTALLDIR]\Configuration\ServerSettings.json" "[C_TEMP]\ServerSettings.json.bak*" /YIR' />
  <CustomAction Id="CopyFromTemp" Property="XCOPY_EXE" Return="ignore" ExeCommand='"[C_TEMP]\ServerSettings.json.bak" "[INSTALLDIR]\Configuration\ServerSettings.json*" /YIR' />

Впоследствии код не изменился до сих пор

<InstallExecuteSequence>
  <Custom Action="CopyToTemp" Before="InstallInitialize">Installed AND (NOT REMOVE="ALL" OR UPGRADINGPRODUCTCODE)</Custom>
  <Custom Action="CopyFromTemp" Before="SetVersionsInRegistry">NOT Installed OR Installed AND (NOT REMOVE="ALL" OR UPGRADINGPRODUCTCODE)</Custom>

.....
</InstallExecuteSequence>

2 ответа

Тестирование условий

Состояние № 1:

Installed AND (NOT REMOVE="ALL" OR UPGRADINGPRODUCTCODE)

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

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

Подвести итоги:

  • Работает: серьезное обновление (запуск через старый MSI, который удаляется, но не в новом MSI), изменение, восстановление
  • Не запускается: первая установка, удаление.

Состояние № 2:

NOT Installed OR Installed AND (NOT REMOVE="ALL" OR UPGRADINGPRODUCTCODE)

Второе условие, которое также немного экзотично, похоже, выполняется только при новой установке и серьезном обновлении. Вам, вероятно, нужно только запустить его во время серьезного обновления, но разве вы не должны запускаться во время ремонта и модификации? (эти режимы также могут перезаписывать файл настроек в некоторых случаях, например, когда REINSTALLMODE установлен на " amus " для принудительной перезаписи файлов).

Подвести итоги:

  • Работает: первая установка, серьезное обновление
  • Не запускается: удалить, изменить, восстановить

Стандартные условия

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

Я бы порекомендовал вообще избегать пользовательских действий, и ниже приведены предлагаемые подходы для достижения этой цели.


Использование приложения для управления файлами настроек

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

Как видно из приведенного выше связанного ответа, часто хорошей идеей является использование вашего приложения для инициализации файлов настроек из копий шаблонов, установленных вашей установкой, в папку "Только для чтения" в INSTALLDIR. Затем вы оставите шаблон без изменений, но при запуске ваше приложение скопирует файл настроек шаблона в профиль каждого пользователя или просто создаст копию в INSTALLDIR, к которой процесс установки никогда не прикоснется (вам потребуется применить разрешение ACL, чтобы сделать это Файл настроек, доступный для записи всем пользователям - не отличный дизайн, но он работает). Этот основанный на шаблонах подход отделяет файл настроек от соображений развертывания. С этого момента он никогда не будет сбрасываться, удаляться или вмешиваться, поскольку он никогда не устанавливался программой установки. Фактически вы должны реализовать его очистку или удаление специально (например, с помощью конструкции RemoveFolder / RemoveFile), или оно останется на диске при удалении, что также может быть проблемой.

Всегда полезно избегать сложной архитектуры установщика Windows для работы с пользовательскими действиями. Существует сложное олицетворение, сложное кондиционирование, сложное упорядочение, а также зависимости времени выполнения для различных двоичных файлов, которые вы вызываете. Вы используете DTF или просто прямую сборку C# для вызова? Есть некоторые проблемы с использованием управляемых пользовательских действий (загружена неправильная версия CLR, вообще не установлена ​​.NET (заблокирована?), Зависимости от файлов в GAC и т. Д. У меня нет полного обзора - я остаюсь по всем этим причинам от всего управляемого кода для развертывания MSI).

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


ОБНОВЛЕНИЕ: я удалил транзитивный подход, который я добавил ранее после того, как дальнейшее тестирование показало, что оно будет работать только в определенных случаях. Я проверю это снова, используя незначительное обновление вместо основного обновления. Затем вы можете использовать незначительное обновление для обновления всей старой версии, чтобы установить файл настроек постоянным, чтобы он никогда больше не удалялся, и тогда вы примените свое основное обновление. Это должно быть возможно обернуть в загрузчик Burn.

ОБНОВЛЕНИЕ: как предполагается (и проверено), незначительное обновление может переключить любой компонент на постоянный, и нет необходимости использовать какие-либо переходные настройки для компонента (я не проверял, может ли незначительное обновление переключить компонент на непостоянный, если он был установлен постоянный раньше). Фактически включение транзитивного режима может фактически деинсталлировать компонент, если какое-либо условие, связанное с компонентом, оценивается как ложное во время установки - я не проверял это, но логично, что это возможно. Первое, что приходит на ум, может ли это удалить компонент, установленный на постоянный. Так не должно быть, но я видел такую ​​странность раньше с MSI. Я могу изобразить это, необходимое для постоянного набора компонентов, развернутого, например, в System32. В заключение: если все, что вам нужно, это сохранить файл настроек, просто используйте незначительное обновление, чтобы установить его постоянным, а затем вы можете снова использовать основные обновления. Не устанавливайте компонент переходным.

Просто упомяну это: ваш файл настроек на самом деле не перезаписывается вашей текущей схемой обновления. Он удаляется и переустанавливается во время основного обновления, поскольку его компонент изначально не был установлен в Permanent = "yes" а также NeverOverwrite="yes", Похоже, это вернуло его к значениям по умолчанию, но оно никогда не перезаписывалось. Скорее это было удалено и повторно установлено, уничтожая изменения. MSI не будет перезаписывать измененные, не версионные файлы, но удачно удалит и переустановит их, если они не помечены как постоянные. На мой взгляд, это технологический анти-паттерн - многие команды постоянно сталкиваются с этой проблемой. Поэтому я предлагаю рассмотреть некоторые варианты развертывания файлов данных, как описано здесь: Создать папку и файл в профиле текущего пользователя из профиля администратора (та же ссылка, что и выше).

Я надеюсь, что это поможет, и, пожалуйста, дайте нам знать, что вы найдете во время тестирования.


СТАРЫЙ ОТВЕТ:

Брайан упомянул реальный совет, но, возможно, некоторые вопросы для уточнения. Я превращу это в попытку ответа, как только у меня будет несколько ответов.

  • Как выполняются эти пользовательские действия? Это команды EXE или вы запускаете программу запуска EXE, которая затем вызывает их? Если вы используете такой лаунчер EXE, это родной (C++) или.NET? (C#/VB.NET). Если это.NET, то это часто плохие новости.
  • Можем ли мы спросить, что вы делаете с этими командами копирования? Может ли это быть сделано в самом приложении более надежно? Это, пожалуй, самый распространенный совет, который мы даем людям, который, если им следовать, может существенно упростить развертывание и сделать его более надежным. У вас больше контроля над тем, что происходит в приложении, вы работаете в предсказуемом контексте безопасности, и вам не нужно заботиться об условиях или последовательности. И наконец: вы можете перезапустить приложение и сделать это снова, настройка "один выстрел".
  • Я оставлю это на этом сейчас...

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

  1. Комментарий / ответ Брайана - они были неправильно подготовлены в этой первоначальной установке, и когда обновление проходит через последовательности в более старой установке, он обнаруживает, что условие оценивается как истинное. Если хотите, нет таких вещей, как установка пользовательских действий или удаление пользовательских действий: есть только пользовательские действия с условиями. В источнике WiX, который был опубликован как обновление, использование UPGRADINGPRODUCTCODE не правильно. Это свойство устанавливается в более старом продукте, когда оно удаляется во время крупного обновления, поэтому любое условие в старой установке, которое говорит "или UPGRADINGPRODUCTCODE", будет истинным. Если вам нужно условие, которое задается в обновленной установке при обновлении более старого продукта, используйте WIX_UPGRADE_DETECTED, как это используется элементом MajorUpgrade.

  2. Акт обновления привел к ремонту старого продукта, и поэтому он запустил пользовательские действия, и они могут даже иметь правильное состояние. Если, например, двоичный файл был заменен и является кандидатом на замену во время вашего обновления, то установщик Windows восстановит и восстановит двоичный файл, который не совпадает, чтобы он мог решить, устанавливать ли его из обновления. Это переустановит функцию, содержащую этот двоичный файл. Поэтому могут выполняться пользовательские действия, обусловленные установкой компонента или компонента.

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

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