При выполнении Major Upgrade в Wix создается 2 записи в разделе "Установка и удаление программ".

Я следовал официальному руководству по мажорному обновлению и, похоже, что-то упустил. Вот мой MCVE:

<?xml version="1.0" encoding="UTF-8"?>

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

  <Product Id="*" Codepage="1252" Language="1033" Manufacturer="Bla Corporation"
           Name="Bla" UpgradeCode="PUT-GUID-HERE" Version="31.00.0000">

    <Package Comments="Contact: Refael Sheinker, refael.sheinker@bla.com." Description="Bla"
             InstallerVersion="500"
             Compressed="yes"
             InstallScope="perMachine"
             Keywords="Installer,MSI,Database" Languages="1033" Manufacturer="Bla Corporation" Platform="x64" />

    <Media Id="1" Cabinet="my_application.cab" EmbedCab="yes" />

    <MajorUpgrade AllowDowngrades="no"
                  AllowSameVersionUpgrades="no"
                  Disallow="no"
                  IgnoreRemoveFailure="no"
                  MigrateFeatures="yes"
                  Schedule="afterInstallInitialize"
                  DowngradeErrorMessage="A later version of [ProductName] is already installed" />

    <Property Id="WIXUI_INSTALLDIR" Value="APPLICATIONROOTDIRECTORY" />
    <UIRef Id="WixUI_InstallDir" />

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFiles64Folder">
        <Directory Id="PROGRAMFILESSUBDIR" Name="Bla">
          <Directory Id="APPLICATIONROOTDIRECTORY" Name="BlaInternal" />
        </Directory>
      </Directory>
    </Directory>

    <DirectoryRef Id="APPLICATIONROOTDIRECTORY">

      <Component Id="tenlira.ini" Guid="*">
        <File Id="tenlira.ini" Source="..\ConfigurationFile\x64\tenlira.ini" KeyPath="yes" />
      </Component>

    </DirectoryRef>

    <Feature Id="MainApplication" Title="TenLira" Level="1">
      <ComponentRef Id="tenlira.ini" />
    </Feature>

  </Product>

</Wix>

Все, что он делает, это просто устанавливает один файл в качестве примера. Все идет нормально. Теперь все, что я делаю, это добавить еще Component а также File и, конечно, соответствующий ComponentRef в Feature, Я специально покидаю Version как есть: 31.00.0000. Я ожидал, что новый установщик не выполнит серьезное обновление, но это произойдет. Зачем? Кроме того, теперь есть 2 записи в Установка и удаление программ.

Пожалуйста, помогите мне узнать, что мне здесь не хватает. Благодарю. Refael.

ОБНОВЛЕНИЕ: отправка вопроса заставила меня перечитать документацию снова, и я обнаружил, что AllowSameVersionUpgrades чтоли в MajorUpgrade элемент должен быть установлен в yes, На этот раз в "Установка и удаление программ" есть только одна запись, но она все еще выполняет "Основное обновление". Зачем?

2 ответа

Решение

Major Upgrade - "Старый, ручной путь"

Я полагаю, что вы столкнулись со странностью, которая не может быть обработана полностью, как ожидается элементом WiX MajorUpgrade, путем объединения auto-generated product GUID, AllowSameVersionUpgrades установлен в yes и сохраняя version number тот же самый.

Я не вижу никакого очевидного способа установить атрибут MinInclusive в элементе MajorUpgrade WiX - я могу ошибаться, возможно, есть какой-то способ, о котором я не знаю. Что бы это ни стоило, я не слишком заинтересован в том, чтобы разрешать "обновления одной и той же версии".

Однако вы можете попытаться "использовать старый способ" для создания таблицы обновлений, используя "старшие элементы" Upgrade и UpgradeVersion. Элемент MajorUpgrade, по сути, представляет собой "удобную" функцию, позволяющую легко настраивать основные обновления, и я считаю, что он работает для большинства пользователей. У Боба Арнсона есть блог, объясняющий введение элемента MajorUpgrade. Этот блог также показывает пример того, как делать вещи "вручную" со "старыми элементами" Upgrade а также UpgradeVersion (проверить это).

Я сделал быстрый макет, который может сделать то, что вы хотите, это просто "черновик" - не могу дать никаких гарантий. Я использую определения препроцессора, чтобы установить некоторые переменные, на которые можно ссылаться в исходном файле WiX - для разработчика на C++ это очень просто, поэтому я не буду тратить время на его объяснение - источник должен иметь смысл:

<?define MyProductVersion = "31.00.0000" ?>
<?define MyProductCode = "PUT-GUID-HERE" ?>
<?define MyUpgradeCode = "PUT-GUID-HERE" ?>

<!--Recommendation: set a path variable that you can redirect at will to a new release folder (new build output folder): -->

<!-- <?define MyBasePath = "C:\Projects\MyApp\Release\31.00.0000\" ?> -->

  <!-- SAMPLE: 
   <Component Win64="yes" Feature="MainApplication">
     <File Source="$(var.MyBasePath)\myapp.exe" />
   </Component> -->

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

  <Product Id="$(var.MyProductCode)" Codepage="1252" Language="1033" Manufacturer="Bla Corporation"
           Name="Bla" UpgradeCode="$(var.MyUpgradeCode)" Version="$(var.MyProductVersion)">

    <Package Comments="Contact: Refael Sheinker, refael.sheinker@bla.com." Description="Bla"
             InstallerVersion="500"
             Compressed="yes"
             InstallScope="perMachine"
             Keywords="Installer,MSI,Database" Languages="1033" Manufacturer="Bla Corporation" Platform="x64" />

    <Media Id="1" Cabinet="my_application.cab" EmbedCab="yes" />

   <!-- Major upgrade -->
    <Upgrade Id="$(var.MyUpgradeCode)">
      <!-- Downgrade Protection -->
      <UpgradeVersion Minimum="$(var.MyProductVersion)" OnlyDetect="yes" IncludeMinimum="yes" Property="DOWNGRADE_DETECTED"  />
      <!-- Major Upgrade Configuration -->
      <UpgradeVersion IncludeMinimum="no" Maximum="$(var.MyProductVersion)" IncludeMaximum="no" MigrateFeatures="yes" Property="UPGRADE_DETECTED"   />
    </Upgrade>

    <!-- Major Upgrade: Schedule RemoveExistingProducts -->
    <InstallExecuteSequence>
      <!-- Potential scheduling (after): InstallValidate, InstallInitialize, InstallExecute, InstallExecuteAgain, InstallFinalize -->
      <RemoveExistingProducts After="InstallInitialize" /> 
    </InstallExecuteSequence>

    <!--Launch Condition: Abort setup if higher version found-->
    <Condition Message="!(loc.NewerVersionDetected)">
      NOT DOWNGRADE_DETECTED
    </Condition>

    <Property Id="WIXUI_INSTALLDIR" Value="APPLICATIONROOTDIRECTORY" />
    <UIRef Id="WixUI_InstallDir" />

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFiles64Folder">
        <Directory Id="PROGRAMFILESSUBDIR" Name="Bla">
          <Directory Id="APPLICATIONROOTDIRECTORY" Name="BlaInternal" />
        </Directory>
      </Directory>
    </Directory>

    <DirectoryRef Id="APPLICATIONROOTDIRECTORY">

      <Component Id="Test.ini" Guid="PUT-GUID-HERE" Win64="yes" Feature="MainApplication">
        <CreateFolder Directory="APPLICATIONROOTDIRECTORY" />
        <IniFile Id="SomeSetting" Action="addLine" Directory="APPLICATIONROOTDIRECTORY" Key="Setting1" Name="Test.ini" Section="MySection" Value="Some Setting" />
        <IniFile Id="OtherSetting" Action="addLine" Directory="APPLICATIONROOTDIRECTORY" Key="Setting2" Name="Test.ini" Section="MySection" Value="Other Setting" />
      </Component>
   </DirectoryRef>

    <Feature Id="MainApplication" Title="TenLira" Level="1">
      <!--<ComponentRef Id="tenlira.ini" />-->
    </Feature>

  </Product>

</Wix>

Теперь !(loc.NewerVersionDetected) должен быть объяснен. Это локализованная строка (для доставки ваших настроек на разных языках). Чтобы использовать его, щелкните правой кнопкой мыши ваш проект WiX в Visual Studio и перейдите: Add New Item... => Localization File => Add, По мере добавления файла локализации ваш выходной MSI теперь также перейдет в en-us папка под вашим основным местом вывода (отладка или выпуск).

В файле локализации добавьте:

<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
    <String Id="NewerVersionDetected">A later version of [ProductName] is already installed.</String>
</WixLocalization>

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

Также добавьте расширение WiX GUI. Right click "References". Add Reference... => Browse to WixUIExtension.dll => Double click this file, and press OK, Обычная папка для поиска файла: C:\Program Files (x86)\WiX Toolset v3.11\bin,


INI-файлы

Я просто хочу упомянуть, что файлы INI в идеале должны устанавливаться через таблицу IniFile (записи обрабатываются как атомарные пары ключ-значение, допускающие расширенное объединение ключей и значений для существующих файлов INI), а не через таблицу File (файл обрабатывается как обычный файл, либо перезаписывает весь существующий файл, либо оставляет его на месте - без применения каких-либо новых значений). Элемент WiX, соответствующий таблице MSI IniFile, естественно, является элементом IniFile.

Специальный образец:

<Component Id="Test.ini" Guid="PUT-GUID-HERE" Win64="yes" Feature="MainApplication">
    <CreateFolder Directory="APPLICATIONROOTDIRECTORY" />
    <IniFile Id="SomeSetting" Action="addLine" Directory="APPLICATIONROOTDIRECTORY" Key="Setting1" Name="Test.ini" Section="MySection" Value="Some Setting" />
    <IniFile Id="OtherSetting" Action="addLine" Directory="APPLICATIONROOTDIRECTORY" Key="Setting2" Name="Test.ini" Section="MySection" Value="Other Setting" />
</Component>

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

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

У меня была такая же проблема, когда версия такая же, но идентификатор отличается, создавая несколько записей в программах добавления / удаления. Мое простое решение - установить AllowSameVersionUpgrades="yes".

<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of $(var.ServiceName) is already installed." />
Другие вопросы по тегам