Обновите индивидуальную функцию в функциях Wix без удаления/обновления других функций (ах)

StackOverflow https://stackoverflow.com/questions/1744105

Вопрос

Я пытаюсь создать проект настройки, используя Викс Это позволит мне установить несколько функций одного продукта. Как я могу обновить одну из установленных функций (которые не зависят от других установленных функций) без необходимости переустановить другие функции в функциональном дереве?

Например, я хочу иметь возможность иметь проект (возвращаясь к Hellowolrd) под названием Hellowolrd, который (неожиданный) печатает «Привет, мир!» на экране. Допустим, у меня есть три из этих приложений Hello World, Hello World 1, Hello World 2 и Hello World 3. Каждый из которых печатает на экране Hello World 1, 2 или 3, с уважением. Я хотел бы создать MSI, который по умолчанию устанавливает все три из этих «функций», но также позволяет обновлять каждую функцию индивидуально в более позднее время.

Вот мой макет моего решения:

Explorer Explorer http://img12.imageshack.us/img12/5671/solutionexplorerm.jpg

Мой файл wix product.wxs выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="ca484210-c719-4b2e-b960-45212d407c11" Name="HelloWorldInstaller" Language="1033" Version="1.0.0.0" Manufacturer="HelloWorldInstaller" UpgradeCode="68eeb8cb-9ef3-443c-870c-9b406129f7ff">
        <Package InstallerVersion="200" Compressed="yes" />

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

        <!-- Create Directory Structure -->
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLLOCATION" Name="Hello World" />
            </Directory>
            <Directory Id="DesktopFolder" Name="Desktop"/>
        </Directory>

        <DirectoryRef Id="INSTALLLOCATION">
            <Component Id="HelloWorld1" Guid="6D1D9D33-DA17-4db3-8132-C39F32200C3A">
                <RegistryKey Root="HKCU" Key="Software\HelloWorldInstaller\HelloWorld1\Install" Action="createAndRemoveOnUninstall">
                    <RegistryValue Name="DTSC" Value="1" Type="integer" KeyPath="yes" />
                </RegistryKey>

                <File Id="HelloWorld1.exe" Name="$(var.HelloWorld1.TargetFileName)" Source="$(var.HelloWorld1.TargetPath)" DiskId="1" Checksum="yes">
                    <Shortcut Id="HelloWorld1ApplicationDesktopShortcut" Name="Hello World 1" Description="Hello World Application 1" Directory="DesktopFolder" WorkingDirectory="INSTALLLOCATION" />
                </File>

            </Component>
            <Component Id="HelloWorld2" Guid="B2D51F85-358B-41a7-8C45-B4BB341158F8">
                <RegistryKey Root="HKCU" Key="Software\HelloWorldInstaller\HelloWorld2\Install" Action="createAndRemoveOnUninstall">
                    <RegistryValue Name="DTSC" Value="1" Type="integer" KeyPath="yes" />
                </RegistryKey>

                <File Id="HelloWorld2.exe" Name="$(var.HelloWorld2.TargetFileName)" Source="$(var.HelloWorld2.TargetPath)" DiskId="1" Checksum="yes">
                    <Shortcut Id="HelloWorld2ApplicationDesktopShortcut" Name="Hello World 2" Description="Hello World Application 2" Directory="DesktopFolder" WorkingDirectory="INSTALLLOCATION" />
                </File>
            </Component>
            <Component Id="HelloWorld3" Guid="A550223E-792F-4169-90A3-574D4240F3C4">
                <RegistryKey Root="HKCU" Key="Software\HelloWorldInstaller\HelloWorld3\Install" Action="createAndRemoveOnUninstall">
                    <RegistryValue Name="DTSC" Value="1" Type="integer" KeyPath="yes" />
                </RegistryKey>

                <File Id="HelloWorld3.exe" Name="$(var.HelloWorld3.TargetFileName)" Source="$(var.HelloWorld3.TargetPath)" DiskId="1" Checksum="yes">
                    <Shortcut Id="HelloWorld3ApplicationDesktopShortcut" Name="Hello World 3" Description="Hello World Application 3" Directory="DesktopFolder" WorkingDirectory="INSTALLLOCATION" />
                </File>
            </Component>
        </DirectoryRef>

        <Feature Id="HelloWorld1Feature" Title="Hello World 1" Level="1">
            <ComponentRef Id="HelloWorld1"/>
        </Feature>
        <Feature Id="HelloWorld2Feature" Title="Hello World 2" Level="1">
            <ComponentRef Id="HelloWorld2"/>
        </Feature>
        <Feature Id="HelloWorld3Feature" Title="Hello World 3" Level="1">
            <ComponentRef Id="HelloWorld3"/>
        </Feature>

    </Product>
</Wix>

Теперь, когда это построено, он устанавливает функции, как и следовало ожидать. Однако, когда вы вносите модификацию Helloworld1.vb и перекомпилируют, я бы хотел, чтобы он мог переустановить (обновлять) только эту функцию, а не все из них.

Когда я обновляю один файл и перестраиваю решение, затем попробуйте установить MSI, я получаю эту ошибку:

Ошибка MSI http://img696.imageshack.us/img696/849/anotherversionisinstall.jpg

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


-Приложение в реальном мире-

Реальное приложение для этого - это большой программный пакет, который требует нескольких приложений поддержки, которые регулярно выполняются в качестве услуг/запланированных задач. Я хотел бы получить установку этих вспомогательных приложений в одну MSI, позволяя нам не иметь такого кошмара развертывания каждого EXE в отдельности. Я знаю, что если у нас есть обновление одного из EXE, что мы могли бы просто вручную скомпилировать это Exe и Dlout Out, но я хотел бы сделать это полностью воспроизводимым образом.

Любая помощь будет оценена,

Благодарю вас!

РЕДАКТИРОВАТЬ:

Я добавил источник для скачивания из Google Code. Анкет Спасибо еще раз!

Это было полезно?

Решение

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

У нас есть умеренно большая часть программного обеспечения, которая требует от нас иметь несколько вспомогательных приложений, которые работают на ряде различных серверов. Наша текущая прогресс обновлений затрудняет обновление кода надежным образом. В настоящее время мы используем самостоятельные извлечения EXE, чтобы развернуть наш код на различные серверы. Проблема возникает, когда у нас есть такое большое количество вспомогательных приложений, что становится трудно убедиться, что приложения были правильно установлены с правильными настройками конфигурации и т. Д. Чтобы решить эту проблему, мы рассматриваем возможность вместо сжимания каждого из Вспомогательные приложения, мы создаем один установщик (MSI), который позволит команде инфраструктуры установить определенный набор вспомогательных приложений для каждой заданной машины. Когда у нас будет значительное изменение (например, с 1,0 до 2.0), мы сделаем полную установку обновления (что означает, что все услуги/процессы должны быть остановлены, не установлены, установлены и начались.) Когда у нас будет незначительное изменение, Мы хотели бы только остановиться и переустановить затронутые услуги/процессы, не касаясь других приложений. Теперь, достаточно бессвязно, давай доберемся до решение:

Я изменил wix product.wxs, чтобы удалить ярлыки, так как они нам не нужны в нашем сценарии. Вот обновленный файл WXS:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
 <Product Id="13C373D3-5C27-487e-A020-C2C89E4607B1" Name="HelloWorldInstaller" Language="1033" Version="1.0.0.0"
      Manufacturer="HelloWorldInstaller" UpgradeCode="E7CB3C76-4D51-48a8-BFB4-6D11B2E2E65B">

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

  <Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
  <FeatureRef Id="HelloWorld1Feature" />
  <FeatureRef Id="HelloWorld2Feature" />
  <FeatureRef Id="HelloWorld3Feature" />
 </Product>

 <Fragment>
  <Directory Id="TARGETDIR" Name="SourceDir">
   <Directory Id="ProgramFilesFolder">
    <Directory Id="INSTALLLOCATION" Name="Hello World" />
   </Directory>
   <Directory Id="DesktopFolder" Name="Desktop"/>
  </Directory>
 </Fragment>

 <Fragment>
  <DirectoryRef Id="INSTALLLOCATION">
   <Directory Id="HelloWorld1Directory" Name="Hello World 1">
    <Component Id="HelloWorld1Component" Guid="6D1D9D33-DA17-4db3-8132-C39F32200C3A">
     <File Id="HelloWorld1.exe" Name="HelloWorld1.exe" Source="HelloWorld1.exe" DiskId="1" Checksum="yes" />    
    </Component>
   </Directory>
   <Directory Id="HelloWorld2Directory" Name="Hello World 2">
    <Component Id="HelloWorld2Component" Guid="B2D51F85-358B-41a7-8C45-B4BB341158F8">
     <File Id="HelloWorld2.exe" Name="HelloWorld2.exe" Source="HelloWorld2.exe" DiskId="1" Checksum="yes" />
    </Component>
   </Directory>
   <Directory Id="HelloWorld3Directory" Name="Hello World 3">
    <Component Id="HelloWorld3Component" Guid="A550223E-792F-4169-90A3-574D4240F3C4">
     <File Id="HelloWorld3.exe" Name="HelloWorld3.exe" Source="HelloWorld3.exe" DiskId="1" Checksum="yes" />
    </Component>
   </Directory>
  </DirectoryRef>
 </Fragment>

 <Fragment>
  <Feature Id="HelloWorld1Feature" Title="Hello World 1" Level="1">
   <ComponentRef Id="HelloWorld1Component"/>
  </Feature>
 </Fragment>
 <Fragment>
  <Feature Id="HelloWorld2Feature" Title="Hello World 2" Level="1">
   <ComponentRef Id="HelloWorld2Component"/>
  </Feature>
 </Fragment>
 <Fragment>
  <Feature Id="HelloWorld3Feature" Title="Hello World 3" Level="1">
   <ComponentRef Id="HelloWorld3Component"/>
  </Feature>
 </Fragment>
</Wix>

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

Например, допустим, у нас есть Producta, которая имеет три компонента - 1,2 и 3. Эти три компонента должны работать либо в качестве услуг, либо запланированными задачами. Характер нашего продукта, мы не можем отключить все наши услуги для обновления или исправления одного из наших компонентов. Итак, если после того, как мы установили версию 1.0, мы находим ошибку в компоненте 2, но мы не хотим, чтобы 1 или 3 были затронуты применением исправления к этой ошибке, мы выпустим патч для компонента 2, Таким образом, будет затронут только компонент 2.

Для нашего быстрой примера выше, мы используем Helloworld1, Helloworld2 и Helloworld3 в качестве 3 наших компонентов в нашем программном приложении. Мысль заключается в том, что мы должны быть в состоянии установить все три с одним MSI, но затем обновлять каждый независимо, не затрагивая ни одно из других установленных компонентов.

Итак, чтобы продемонстрировать это, я создал три приложения консоли, которые покажут «Привет, мир 1!», «Привет, World 2!» И «Hello World 3!». Затем, после того, как мы выпустим первоначальный MSI, скажем, мы находим «ошибку», которая требует от нас, чтобы мы могли сказать «Hello World 1! Обновлено». вместо. Вот что мы сделаем, чтобы имитировать это:

  1. Создайте product.wixobj, выполнив эту команду в командной строке:
    candle.exe Product.wxs
    Пожалуйста, помните, что для того, чтобы позвонить в Candle.exe или любую команд WIX, каталог установки WIX должен быть в переменной вашего пути. (Короткое руководство по обновлению переменной среды пути) Также, пожалуйста, выполните команды в том же каталоге, что и ваш файл product.wxs.
  2. Создайте первую версию вашего продукта (скажем, 1.0):
    light.exe Product.wixobj -out ProductA-1.0.msi
  3. Теперь найдите ошибку (измените вывод Helloworld1, чтобы сказать «Привет, мир 1! Обновлено») Тогда тогда Обновите версию сборки и версию файла. Анкет Это важно, так как именно так Wix может сказать, что EXE отличаются.
  4. Запустите ту же команду, что и первый шаг (для хорошей меры):
    candle.exe Product.wxs
  5. Запустите почти ту же команду, что и шаг второй:
    light.exe Product.wixobj -out ProductA-1.1.msi
    Обратите внимание, что это версия 1.1 вместо 1.0 (это MSI с нашим обновленным кодом). Однако мы не хотим просто устанавливать это, Продолжай читать.
  6. Вот забавная часть, мы получаем разницу в двух MSIS со следующей командой:
    torch.exe -p -xi ProductA-1.0.wixpdb ProductA-1.1.wixpdb -out Diff.WixMst
  7. Теперь мы создаем из этого файла патча (patch.wxs будет объяснена ниже):
    candle.exe Patch.wxs
  8. Теперь мы создадим файл wixmsp с этой командой:
    light.exe Patch.wixobj -out Patch.WixMsp
  9. А теперь самая забавная часть. Создайте файл MSP с помощью этой команды:
    pyro.exe Patch.WixMsp -out Patch.msp -t RTM Diff.Wixmst

Теперь, если все пошло по плану, у вас должно быть два MSI и один файл MSP. Если вы установите первый MSI (producta-1.0.smi) и запустите Helloworld1.exe, вы должны увидеть сообщение «Привет, мир 1!». Просто для развлечения (и, пример), запустите оба других приложения и оставьте их запуска (я построил остановку, чтобы держать их открытыми). Close helloworld1.exe, поскольку мы сейчас собираемся применить обновление для этого EXE, но при этом мы не повлияем на Helloworld2.exe или Helloworld3.exe. Если вы теперь установите файл MSP (patch.msp), а затем запустите helloWorld1.exe, вы увидите обновленное сообщение «Hello World 1! Обновлено».

Теперь для магический FATH.WXS Файл:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
 <Patch
   AllowRemoval="yes"
   Manufacturer="Dynamo Corp"
   MoreInfoURL="http://www.dynamocorp.com/"
   DisplayName="Sample Patch"
   Description="Small Update Patch"
   Classification="Update"
        >

  <Media Id="5000" Cabinet="RTM.cab">
   <PatchBaseline Id="RTM"/>
  </Media>

  <PatchFamilyRef Id="SamplePatchFamily"/>
 </Patch>

 <Fragment>
  <PatchFamily Id='SamplePatchFamily' Version='1.0.0' Supersede='yes'>
   <ComponentRef Id="HelloWorld1Component"/>
  </PatchFamily>
 </Fragment>
</Wix>

Не выглядит так много, не так ли? Ну, самые интересные части - это:

  1. <PatchBaseline Id="RTM"/> - Это, если вы помните, используется в нашем создании патча MSI. «RTM» упоминается на последнем этапе выше: -t RTM - Они должны соответствовать.
  2. <ComponentRef Id="HelloWorld1Component"/> - Это указывает на патч на правильный компонент для обновления, в нашем случае Helloworld1component.

Если вы выполняли какой -либо поиск, приведенный выше код может показаться знакомым, потому что он пришел из Блог Питера Марку: Wix: Создание патча с использованием новой системы строительства патча - Часть 3

Я также сильно полагался на Блог Алекса Шевчука: От MSI до Wix, часть 8 - Основное обновление

Если вам интересно: «Ух ты, это много шагов, зачем кому -то делать это много шагов?», Помните, что, как только сделана тяжелая работа (выше), вам нужно перенести это в свою процедуру интеграции. Это верно, интегрировать, интегрировать, интегрировать! Как ты это делаешь? Ну, это немного больше исследований и, может быть, пост в блоге? - Вероятно. Чтобы вытащить вас на правую ногу, вот потрясающая статья о Автоматизирующие выбросы с MSBuild и установщиком Windows XML.

Вау, я надеюсь, что вы прочитали все это (все вас двое) и многому научились. Я надеюсь, что это поможет кому -то, кроме меня.

Благодарю вас!

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top