Условная функция WiX / компонент, потерянный при удалении - PullRequest
3 голосов
/ 15 сентября 2011

Редактировать: Цитирую себя, потому что я изложил проблему намного лучше в одном из комментариев ниже ...

У меня есть условие, которое верно, когда пакет установлен, но не правда, когда это удалено. Я ожидал, что MSI вспомнит, что установил условный компонент и удалил его при деинсталляции, Но это не так. Я пытаюсь выяснить а) правильный способ очистить этот осиротевший компонент, и B) лучший способ защитить против этой проблемы в будущем.

Полагаю, мой вопрос сводится к тому, безопасно ли просто удалять потерянные функции / компоненты после удаления продукта? И есть ли способ проверить, что, если вообще, все еще ссылается на компонент, который я считаю сиротой? И как мне исправить мой установщик, чтобы предотвратить это в будущем?

У нас есть проект wix для установки библиотеки Foo. Этот установщик помещает копии файла Foo.dll в GAC и в папку Program Files\Reference Assemblies\Foo\<version> по умолчанию. Установщик также добавляет два ключа реестра, один из которых является пользовательским ключом, в котором хранится путь к папке Foo для повторного использования в будущих установках, а другой говорит Visual Studio, что при поиске установленных библиотек следует включать полный путь к папке <version>, чтобы Foo отображается в диалоговом окне «Добавить ссылки». На машине может быть установлено несколько версий библиотеки Foo одновременно, каждая из которых будет расположена в соответствующей папке <version> в папке Foo.

В Foo 2.0.0 была ошибка, которая просочилась во время тестирования, Foo 2.0.1 содержала исправление ошибки, никаких других изменений. Было решено, что, поскольку исправление ошибки было единственным изменением, мы добавили бы файл политики в GAC, который перенаправлял бы ссылки для Foo 2.0.0 в Foo 2.0.1. Этот файл политики был добавлен в программу установки в качестве нового компонента внутри новой функции. Был добавлен тег обновления для обнаружения и удаления Foo 2.0.0 при установке Foo 2.0.1. Установка функции политики была сделана условной при обнаружении Foo 2.0.0. Казалось, все работает, и Foo 2.0.1 был вытолкнут.

Теперь, год спустя, мы обнаруживаем, что снова пропустили замечение ошибки, на этот раз в настройке программы установки, а не в коде библиотеки. Оказывается, что когда Foo 2.0.1 заменяет 2.0.0, а затем удаляется, файл политики теряется и остается в GAC, а все остальные файлы и ключи удаляются. Я проверил это на чистой установке Windows (виртуальные машины могут быть очень полезны) и подтвердил, что проблема может быть воспроизведена, то есть никакие дополнительные ссылки на компонент не проникли, чтобы заставить его остаться.

Все это изначально было сделано в WiX 3.0, но недавно мы перешли на использование WiX 3.5. Наш код WiX выглядит следующим образом:

<Product Id="Guid 1" Name="Foo v2.0.1" Language="1033" Version="2.0.1" Manufacturer="My Team" UpgradeCode="Guid 2">

  <Package InstallerVersion="300" Compressed="yes" />

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

  <Upgrade Id="Guid 2">
    <UpgradeVersion Minimum="2.0.0" Maximum="2.0.0" IncludeMaximum="yes" IncludeMinimum="yes" OnlyDetect="no" Property="UPGRADE2X0X0"></UpgradeVersion>
  </Upgrade>

  <Property Id="FOODIR">
    <RegistrySearch Id="FooPath" Type="directory" Root="HKLM" Key="Software\Foo" Name="InstallPath"></RegistrySearch>
  </Property>

  <Directory Id="TARGETDIR" Name="SourceDir">
    <Directory Id="ProgramFilesFolder">
      <Directory Id="RefAssemb" Name="Reference Assemblies">
        <Directory Id="FOODIR" Name="Foo">
          <Component Id="FooLibPath" Guid="Guid 3">
            <RegistryKey Root="HKLM" Key="Software\Foo" Action="createAndRemoveOnUninstall">
              <RegistryValue Name="InstallPath" Type="string" Value="[FOODIR]" KeyPath="yes"></RegistryValue>
            </RegistryKey>
          </Component>
          <Directory Id="FOOVERSION" Name="v2.0.1">
            <Component Id="Foo_VSFile" Guid="Guid 4">
              <File Id="Foo_DLL" Source="$(sys.CURRENTDIR)2.0.1\Foo.dll" KeyPath="yes"></File>
            </Component>
            <Component Id="Foo_VSRegKey" Guid="Guid 5">
              <RegistryKey Root="HKLM" Key="SOFTWARE\Microsoft\.NETFramework\v3.5\AssemblyFoldersEx\Foo v2.0.1" Action="createAndRemoveOnUninstall">
                <RegistryValue Type="string" Value="[FOOVERSION]" KeyPath="yes"></RegistryValue>
              </RegistryKey>
            </Component>
            <Directory Id="FOOGAC" Name="GAC">
              <Component Id="Foo_GAC" Guid="Guid 6">
                <File Id="Foo" Source="$(sys.CURRENTDIR)2.0.1\Foo.dll" KeyPath="yes" Assembly=".net"></File>
              </Component>
              <Component Id="Foo_Policy_2x0x1" Guid="Guid 7">
                <File Id="Foo_PolicyDLL" Source="$(sys.CURRENTDIR)2.0.1\policy.2.0.Foo.dll" KeyPath="yes" Assembly=".net"></File>
                <File Id="Foo_PolicyConfig" Source="$(sys.CURRENTDIR)2.0.1\policy.2.0.Foo.config" CompanionFile="Foo_PolicyDLL"></File>
              </Component>
            </Directory>
          </Directory>
        </Directory>
      </Directory>
    </Directory>
  </Directory>

  <Feature Id="ProductFoo" Level="1">

      <ComponentRef Id="Foo_GAC"/>

      <Feature Id="Foo_VSSupport" Level="1">
        <ComponentRef Id="FooLibPath"/>
        <ComponentRef Id="Foo_VSFile"/>
        <ComponentRef Id="Foo_VSRegKey"/>
      </Feature>

      <Feature Id="Foo_Policy_v2x0x1" Level="0">
        <ComponentRef Id="Foo_Policy_2x0x1"/>
        <Condition Level="1">UPGRADE2X0X0</Condition>
      </Feature>

  </Feature>

</Product>

1 Ответ

1 голос
/ 15 сентября 2011

безопасно ли просто удалить потерянную функцию / компонент после удаления продукта?

Нет, это не так.Если вы просто удалите его, информация о регистрации его компонента все еще останется на компьютере.

И есть ли способ проверить, что, если вообще что-то, ссылается на компонент, который я считаю сиротой?

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

Маловероятно, что случайный продукт будет ссылаться на вашкомпонент или сборка.

И как мне исправить мой установщик, чтобы предотвратить это в будущем?

Использовать крупные обновления, которые удаляют старый компонент и устанавливают новыйодин.Никаких специальных файлов политики, никаких условных установок или удалений.

Одновременно на компьютере может быть установлено несколько версий библиотеки Foo, каждая из которых будет находиться в соответствующей папке в папке Foo.

Почему?Если у вас есть один продукт, вы можете использовать основные обновления.Таким образом, у пользователя будет установлена ​​только одна версия с одной версией вашей сборки.

Версии сборок, установленные бок о бок, имеют смысл только для разных продуктов.

Было решено, чтопоскольку исправление ошибки было единственным изменением, мы добавили бы файл политики в GAC, который перенаправлял бы ссылки для Foo 2.0.0 на Foo 2.0.1.Этот файл политики был добавлен в установщик как новый компонент внутри новой функции.

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

Основные обновления всегда должны быть автономными.

...