как сделать так, чтобы WIX не удалял определенные файлы при выполнении крупного обновления

У меня есть два компонента, в которых один компонент имеет simple.exe, а другой компонент sample.dll в одном MSI. Если я установлю MSI, будут установлены и simple.exe, и sample.dll, а в программных файлах в какой-то папке будет два: .exe и .dll. Если я сделаю серьезное обновление всего MSI, он заменит папку, созданную в файлах программы, новой. Итак, как заставить wix не заменять .exe, если я изменяю / предоставляю обновление для файла .dll и наоборот. И при обновлении .dll я буду регистрировать и отменять регистрацию ключей с помощью какого-нибудь .bat файла. Пожалуйста, помогите мне решить эту проблему. Мне нужно условное серьезное обновление, которое заменит определенные файлы при их изменении.

Пожалуйста, найдите приведенный ниже код:

product.wxs

<?xml version="1.0" encoding="UTF-8"?>
<?define ProductVersion = "0.0.4"?>
<?define ProductUpgradeCode = "d3170abf-b41c-4274-a3a0-85576052f35c"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="*" Name="saranSample" Language="1033" Version="$(var.ProductVersion)" Manufacturer="example" UpgradeCode="$(var.ProductUpgradeCode)">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <MajorUpgrade DowngradeErrorMessage="A newer version of product is already installed." AllowSameVersionUpgrades="no" AllowDowngrades="no" />
    <MediaTemplate EmbedCab="yes" />

<Upgrade Id="$(var.ProductUpgradeCode)">
  <UpgradeVersion Minimum="$(var.ProductVersion)" OnlyDetect="yes" Property="NEWERVERSIONDETECTED"/>
  <UpgradeVersion Minimum="0.0.0" Maximum="$(var.ProductVersion)" IncludeMinimum="yes" IncludeMaximum="no" Property="OLDERVERSIONBEINGUPGRADED"/>
</Upgrade>
<InstallExecuteSequence>
  <Custom Action="Filecleaner" After="InstallFinalize"></Custom>
</InstallExecuteSequence>
<Condition Message="A newer version of this software is already installed.">NOT NEWERVERSIONDETECTED</Condition>

    <Directory Id="TARGETDIR" Name="SourceDir">
        <Directory Id="ProgramFilesFolder">
    <Directory Id="INSTALLFOLDER" Name="saranSample_$(var.ProductVersion)">
      <Component Id="exeFiles" Guid="12345678-1234-1234-1234-222222222222">
        <File Id="exe" Source="$(sys.CURRENTDIR)npp.7.5.7.Installer.exe" KeyPath="yes"/>
      </Component>
      <Component Id="dllFiles" Guid="12345678-1234-1234-1234-222222222223">
        <File Id="dll" Source="$(sys.CURRENTDIR)saran.dll" KeyPath="yes"/>
      </Component>
    </Directory>
        </Directory>
    </Directory>

<Feature Id="ProductFeature" Title="saranSample" Level="1">
  <ComponentRef Id="exeFiles"/>
  <ComponentRef Id="dllFiles"/>
</Feature>


person saran    schedule 19.07.2018    source источник


Ответы (2)


Я поддерживаю все точки зрения Фила и, возможно, могу добавить пару вещей:

Один файл на компонент. Убедитесь, что вы используете один компонент для каждого файла, который вы устанавливаете. Я делаю это для всех типов файлов, но вы должны делать это для двоичных файлов (dll и exes). Это сделано для того, чтобы программа установки работала правильно и в соответствии с правилами компонентов MSI (упомянутыми Филом). Я вижу, у вас есть компонентные EXE-файлы и один для DLL-файлов. Создайте новые компоненты для каждого двоичного файла, который вы добавляете в свою установку, и установите двоичный файл в качестве ключевого пути для компонента.


Выборочное обновление файлов: если вы хотите сохранить старые версии файлов на диске при установке нового пакета с файлами более поздних версий выборочно , то я не знаю, как это сделать, кроме попытки установить файлы только для чтения (чего я никогда не пробовал - честно говоря, не уверен, что произойдет). Вы также можете установить пустой GUID компонента (такой GUID также известен как "Little Bobby Void-GUID", просто проверьте этот очень официальный источник) - это установит один или несколько файлов и никогда больше не будет касаться и перезаписывать их. Существует также флаг компонента, который может быть установлен на никогда не перезаписывать, если путь ключа компонента существует (я обычно совмещаю это с установкой компонента постоянным). Также можно подделать номер версии файла путем пост-обработки созданного вами MSI. Некоторые сторонние инструменты, такие как Installshield и Advanced Installer, предоставляют графический интерфейс для этого перед компиляцией.

MSI обычно перезаписывает только файлы более низкой версии в целевом расположении двоичными файлами более поздней версии в настройке (это соответствует умолчанию _ 2_, на который можно повлиять и изменить, установив пользовательское значение для _ 3_ -" модификатор "для правил перезаписи файлов). Если файлы в целевом месте назначения имеют ту же или более позднюю версию, чем устанавливаемые, то целевые файлы не будут перезаписаны (если для REINSTALLMODE не установлено значение amus - принудительная перезапись - что является ужасной концепцией и имеет множество побочных эффектов).

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


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


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

Вышеупомянутая функция / подход к крупному обновлению с поздним последовательным обновлением предотвращает эту проблему с возвратом файла настроек, потому что файлы не удаляются и не переустанавливаются в обычном порядке, а сравниваются между версиями установки и остаются нетронутыми, если это файлы настроек с изменениями - при условии, что вы все выполнили. правильно в соответствии с правилами компонентов MSI, и это не пикник. Вам необходимо 100% соответствие правилам компонентов, чтобы избежать других побочных эффектов, таких как, например, отсутствие файлов после завершения обновления. Краткое описание правил для компонентов.

Кроме того, вы можете сделать файлы настроек постоянными в своем MSI-файле. Тогда они никогда не будут удалены, но также, вероятно, никогда не будут обновлены и никогда не будут удалены, если вы не создадите для этого свои собственные конструкции.


Переменные пути. Вам подходит $(sys.CURRENTDIR)? Мне нравится определять свою собственную переменную пути, которую я могу с легкостью перенести в любую папку, которую я хочу:

<?define SourceFiles= "C:\Projects\MySetup\Releases\1.0.0\"?>

<...>

<Icon Id="Icon.exe" SourceFile="$(var.SourceFiles)\MyApp.exe" />

Некоторые ссылки:

person Stein Åsmul    schedule 20.07.2018

Несколько вещей:

  1. Почему у вас есть элемент MajorUpgrade, а также элементы Upgrade? Элемент MajorUpgrade должен быть всем, что вам нужно, так что это сбивает с толку.

  2. Как и в документации MajorUpgrade, последовательность обновления по умолчанию - afterInstallValidate. Это «ранний» этап обновления, и он эффективно удаляет все старые продукты перед установкой новой версии. Вот почему файлы удаляются (при деинсталляции), а затем устанавливаются снова.

  3. Похоже, вам нужно, чтобы ваше расписание MajorUpgrade было послеInstallExecute. При этом новые файлы продукта устанавливаются поверх старых файлов с использованием правил перезаписи версий файлов. Если версии двоичных файлов не изменились, они не будут заменены. Этот тип обновления также требует, чтобы вы следовали правилам компонентов:

http://robmensching.com/blog/posts/2003/10/18/component-rules-101/

https://docs.microsoft.com/en-us/windows/desktop/msi/what-happens-if-the-component-rules-are-broken

Кроме того, вы упоминаете регистрацию с использованием файла bat, а это не обязательно. WiX имеет инструмент Heat для извлечения регистрации при сборке ti, e.

person PhilDW    schedule 19.07.2018