Функции, установленные в разных местах, но ссылающиеся на одни и те же компоненты

У меня есть продукт, который состоит из нескольких функций, которые можно установить в разных местах, например, Feature 1 - это исполняемый файл, установленный в Program Files, а Feature 2 - это веб-сайт, установленный в wwwroot. Тем не менее, как Feature 1, так и Feature 2 полагаются на множество одинаковых dll и, следовательно, требуют, чтобы компоненты, содержащие эти dll, были установлены в 2 разных местах, в зависимости от того, какие компоненты установлены.

Есть ли способ достичь этого, не определяя каждый компонент дважды?

Чтобы предоставить еще один полный пример того, чего я пытаюсь достичь, следующий полный файл wxs можно скомпилировать с помощью:

> свеча Foobar.wxs

> light.exe -ext WixUIExtension Foobar.wixobj

> msiexec / i Foobar.msi

<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>

  <Product Name='Foobar 1.0' 
           Id='E578DF12-DDE7-4BC2-82CD-FF11862862D5' 
           UpgradeCode='90F09DD5-E01B-4652-8971-515997730195'
           Language='1033' 
           Codepage='1252' 
           Version='1.0.0' 
           Manufacturer='Acme Ltd.'>

    <Package Id='*' 
             Keywords='Installer'
             Description="Acme 1.0 Installer"
             InstallerVersion='100' 
             Languages='1033' 
             Compressed='yes' 
             SummaryCodepage='1252' />

    <Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" />
    <Property Id='DiskPrompt' Value="Acme 1.0 Installation" />

    <Directory Id='TARGETDIR' Name='SourceDir'>
         <!-- Directory 1 (Program Files) -->
        <Directory Id="ProgramFilesFolder" Name="PFiles">
            <Directory Id="PROGRAM_INSTALLDIR" Name="Acme" />
        </Directory>

        <!-- Directory 2 (wwwroot) -->
        <Directory Id="Inetpub" Name="Inetpub">
            <Directory Id="wwwroot" Name="wwwroot">
                <Directory Id="WEBSITE_INSTALLDIR" Name="AcmeWebSite" />
            </Directory>
        </Directory>
    </Directory>

    <DirectoryRef Id='PROGRAM_INSTALLDIR'>
        <Component Id="Component1" Guid="79EC9E0B-8325-427B-A865-E1105CB16B62">
            <File Id="File1" Name="File1.txt" Source="File1.txt" />
        </Component>
    </DirectoryRef>

    <DirectoryRef Id='WEBSITE_INSTALLDIR'>
        <Component Id="Component2" Guid="702E6573-8FBC-4269-A58D-FD1157111F0F">
            <File Id="File2" Name="File2.txt" Source="File2.txt" />
        </Component>
    </DirectoryRef>

    <Feature Id="Feature.Program" 
             Title="My Program" 
             TypicalDefault="install" 
             Level="1" 
             ConfigurableDirectory="PROGRAM_INSTALLDIR" >
        <ComponentRef Id="Component1"/>
        <ComponentRef Id="Component2"/>
    </Feature>

    <Feature Id="Feature.Website" 
             Title="My Website" 
             TypicalDefault="install" 
             Level="1" 
             ConfigurableDirectory="WEBSITE_INSTALLDIR" >
        <ComponentRef Id="Component1"/>
        <ComponentRef Id="Component2"/>
    </Feature>

    <UIRef Id="WixUI_Mondo" />
    <UIRef Id="WixUI_ErrorProgressText" />

  </Product>
</Wix>

Это, однако, приведет к установке ТОЛЬКО File1.txt в

C:\Program Files (x86)\Acme

и ТОЛЬКО File2.txt устанавливается в

_C:\Inetpub\ Wwwroot\AcmeWebsite_

Одно решение состоит в том, чтобы определить компоненты дважды, такие как:

<DirectoryRef Id='PROGRAM_INSTALLDIR'>
    <Component Id="Component1" Guid="79EC9E0B-8325-427B-A865-E1105CB16B62">
        <File Id="File1" Name="File1.txt" Source="File1.txt" />
    </Component>
    <Component Id="Component2" Guid="702E6573-8FBC-4269-A58D-FD1157111F0F">
        <File Id="File2" Name="File2.txt" Source="File2.txt" />
    </Component>
</DirectoryRef>

<DirectoryRef Id='WEBSITE_INSTALLDIR'>
    <Component Id="Component1.Web" Guid="397E93AA-32FB-425A-A783-386E0CCA2357">
        <File Id="File1.Web" Name="File1.txt" Source="File1.txt" />
    </Component>
    <Component Id="Component2.Web" Guid="5C3AFF06-3623-4524-A90B-72B46DE5572A">
        <File Id="File2.Web" Name="File2.txt" Source="File2.txt" />
    </Component>
</DirectoryRef>

<Feature Id="Feature.Program" 
         Title="My Program" 
         TypicalDefault="install" 
         Level="1" 
         ConfigurableDirectory="PROGRAM_INSTALLDIR" >
    <ComponentRef Id="Component1"/>
    <ComponentRef Id="Component2"/>
</Feature>

<Feature Id="Feature.Website" 
         Title="My Website" 
         TypicalDefault="install" 
         Level="1" 
         ConfigurableDirectory="WEBSITE_INSTALLDIR" >
    <ComponentRef Id="Component1.Web"/>
    <ComponentRef Id="Component2.Web"/>
</Feature>

Но что произойдет, если мы добавим третью функцию, которая должна быть установлена ​​в другом месте? Должны ли мы снова переопределять каждый компонент? С более чем 100 компонентами управление дублирующимися компонентами станет большой работой.

Какие-либо предложения?

3 ответа

Решение

Вы видите ограничение в установщике Windows. Компонент может быть установлен только один раз через MSI. Каждый компонент может быть установлен только в один каталог. Чтобы содержимое компонента было установлено в двух разных местах, необходимо либо создать другой компонент с тем же содержимым, либо попытаться использовать элемент CopyFile для дублирования содержимого.

Вероятно, не то, что вы хотели услышать, но именно так работает установщик Windows.

К счастью, если вы выбрали вариант 1, то набор инструментов WiX будет сжимать дублированный контент по компонентам только один раз. Умная порка!

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

Чтобы отметить функцию для установки, вы можете использовать функцию MsiSetFeatureState: http://msdn.microsoft.com/en-us/library/aa370387(VS.85).aspx

Настраиваемое действие, которое делает это, может быть обусловлено действием функции ваших функций: http://msdn.microsoft.com/en-us/library/aa368561(VS.85).aspx

Функции могут ссылаться на каталог для возможности просмотра, но это может что-то значить, только если компоненты используют каталоги, являющиеся этим каталогом, или дочерние элементы этого каталога. В противном случае компонент перейдет в указанный каталог. Другими словами, у вас может быть INSTALLDIR для функции, а у большинства компонентов еще есть ANOTHERDIR (скажем, [CommonFilesFolder]Company\Shared для другого компонента, и он пойдет туда. Затем этот компонент может принадлежать нескольким функциям, и все будет в порядке.

Другие вопросы по тегам