Причина такого переезда заключается в том, что у нас возникали проблемы при каждом обновлении, когда файлы конфигурации перезаписывались. Поэтому мы решили скопировать их во временную папку с помощью специального действия (предустановка) и после установки перенесли обратно в папку установки (после установки). Это будет сделано при каждом обновлении. До сих пор это работало хорошо. Единственное, что мы изменили, это заменили xcopy на robocopy, и теперь на udpate он по-прежнему использует старое настраиваемое действие, даже в файлах журнала написано «robocopy», но старые имена файлов в конфигурационных папках все еще создаются ... При более глубоком рассмотрении, когда Я вернулся в офис. Пока спасибо

наружили странное поведение с помощью 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>
 Cabe Skuriles05 янв. 2018 г., 10:16
Спасибо за объяснение. Я добавил пользовательские действия, которые мы изменили. Но, насколько я понимаю, установка всегда использует старые пользовательские действия из установленных версий вместо новой установки. Затем мы должны проверить, можем ли мы обработать это иначе ..
 Stein Åsmul13 янв. 2018 г., 04:35
Хорошо, читая мое предыдущее обновление, я увидел несколько проблем. Я снова обновил свой ответ, и на этот раз я надеюсь и верю, что новая информация может оказаться полезной.
 Brian Sutherland22 дек. 2017 г., 16:42
При обновлении MSI запускает старую установку, чтобы удалить ее. Если вы не создали его с правильным условием для настраиваемого действия, оно запустится во время удаления. При обновлении более старой версии до версии 2.2.5+ вы сможете лучше понять, что происходит с журналами, используя "/ l * v msiLog.txt" при установке новой версии msi. Можете ли вы добавить старое определение и расписание настраиваемых действий и новое в исходный вопрос?
 Stein Åsmul12 янв. 2018 г., 02:50
Я обновил свой ответ новой информацией. Кажется, что ваши условия для этих пользовательских действий не идеальны для предполагаемого поведения, которое вы описываете, хотя я не совсем понимаю, как именно они должны работать. Пожалуйста, смотрите детали ниже.

Ответы на вопрос(2)

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

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

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

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

 Cabe Skuriles23 дек. 2017 г., 07:35
Причина такого переезда заключается в том, что у нас возникали проблемы при каждом обновлении, когда файлы конфигурации перезаписывались. Поэтому мы решили скопировать их во временную папку с помощью специального действия (предустановка) и после установки перенесли обратно в папку установки (после установки). Это будет сделано при каждом обновлении. До сих пор это работало хорошо. Единственное, что мы изменили, это заменили xcopy на robocopy, и теперь на udpate он по-прежнему использует старое настраиваемое действие, даже в файлах журнала написано «robocopy», но старые имена файлов в конфигурационных папках все еще создаются ... При более глубоком рассмотрении, когда Я вернулся в офис. Пока спасибо
Тестирование условий

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

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

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

Обобщить:

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

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

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

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

Обобщить:

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

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

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

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

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

Как видно из приведенного выше связанного ответа, часто хорошей идеей является использование вашего приложения для инициализации файлов настроек из копий шаблонов, установленных вашей установкой, в папку «Только для чтения» в 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, то это часто плохие новости.Можем ли мы спросить, что вы делаете с этими командами копирования? Может ли это быть сделано в самом приложении более надежно? Это, пожалуй, самый распространенный совет, который мы даем людям, который, если им следовать, может существенно упростить развертывание и сделать его более надежным. У вас больше контроля над тем, что происходит в приложении, вы работаете в предсказуемом контексте безопасности, и вам не нужно заботиться об условиях или последовательности. И наконец: вы можете перезапустить приложение и сделать это снова, настройка «один выстрел».Я оставлю это на этом сейчас ...
 Cabe Skuriles13 янв. 2018 г., 06:24
Вау ... спасибо за это подробное объяснение. Мы заставили все это работать, поскольку мы переместили весь процесс резервного копирования и восстановления в пользовательское действие C #, которое теперь отлично работает для нашего установщика.

Ваш ответ на вопрос