2011-02-09 12 views
8

Ho un prodotto che comprende più funzionalità che possono essere installate in posizioni diverse, ad es. La caratteristica 1 è un eseguibile installato in Program Files e Feature 2 è un sito Web installato in wwwroot. Tuttavia, sia la caratteristica 1 che la caratteristica 2 si basano su molte delle stesse dll e, pertanto, richiedono che i componenti contenenti tali dll vengano installati in 2 posizioni diverse a seconda delle funzioni installate.Funzioni installate in posizioni diverse ma facendo riferimento agli stessi componenti

C'è un modo per raggiungere questo risultato senza definire ogni componente due volte?

Per fornire un ulteriore esempio completo di quello che sto cercando di realizzare, il seguente file WXS completo può essere compilato utilizzando:

> candle.exe 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> 

Ciò tuttavia comportare SOLO File1.txt installato in

C: \ Program Files (x86) \ Acme

e SOLO file2.txt installato in

_C: \ Inetpub \ wwwroot \ AcmeWebsite_

una soluzione è quella di definire i componenti per due volte come ad esempio:

<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> 

Ma allora cosa succede se aggiungiamo una terza funzione che deve essere installata in un'altra posizione? Dobbiamo quindi ridefinire nuovamente ogni componente? Con oltre 100 componenti, la gestione di componenti duplicati diventerà un grande lavoro.

Qualche suggerimento?

+1

Per chiunque cerchi come è stato risolto questo problema, ho finito per utilizzare il Metodo 3 da questo [articolo di supporto Microsoft] (http://support.microsoft.com/kb/837908) in modo che il sito Web potesse caricare le sue DLL dal percorso del cestino Programmi e installato una copia singola delle DLL lì. È necessario duplicare solo un numero limitato di DLL perché sono necessarie per caricare l'app Web prima che possa configurare il gestore AssemblyResolve. Il nostro software è un po 'strano in quanto il sito web utilizza la riflessione per caricare un numero elevato di oggetti da un numero elevato di DLL, rendendo la definizione di componenti duplicati o la definizione di – Casey

risposta

14

Si nota una limitazione in Windows Installer. Un componente può essere installato solo una volta tramite un MSI.Ogni componente può essere installato solo in una singola directory. Per avere il contenuto di un componente installato in due posizioni diverse, è necessario creare un altro componente con lo stesso contenuto o provare a utilizzare l'elemento CopyFile per duplicare il contenuto.

Probabilmente non è quello che volevi sentire, ma questo è il modo in cui Windows Installer funziona.

Fortunatamente, se si sceglie di utilizzare l'opzione 1, il set di strumenti WiX comprimerà solo il contenuto duplicato tra i componenti una sola volta. Smart cabbing rocks!

1

Si consiglia di creare una funzione separata che contiene solo i componenti comuni. Non dovrebbe essere installato di default. È quindi possibile creare un'azione personalizzata che contrassegna questa funzione per l'installazione solo quando è installata una delle funzionalità effettive.

Per contrassegnare la funzione per l'installazione è possibile utilizzare la funzione MsiSetFeatureState: http://msdn.microsoft.com/en-us/library/aa370387(VS.85).aspx

L'azione personalizzata che fa questo può essere condizionato con l'azione funzione delle vostre caratteristiche: http://msdn.microsoft.com/en-us/library/aa368561(VS.85).aspx

+0

Ancora non capisco come questo aiuti a installare i componenti comuni a 2 posizioni diverse come specificato da ciascuna funzione. Forse potresti approfondire come vedi che funziona? – Casey

+1

Perché si desidera duplicare i componenti comuni? Solitamente le risorse comuni vengono collocate in un luogo pubblico (ad esempio File Programmi \ Common) e tutti i prodotti li utilizzano da questa posizione. –

0

Caratteristiche possono fare riferimento a una directory per funzionalità di ricerca, ma ciò significa solo qualcosa se i componenti utilizzano le directory che sono quella directory o un figlio di quella directory. Altrimenti il ​​componente andrà nella directory specificata. In altre parole, potresti avere INSTALLDIR per la funzionalità e la maggior parte dei componenti ha ANOTHERDIR (diciamo [CommonFilesFolder] Company \ Shared per un altro componente e andrà lì. Quel componente può quindi appartenere a più funzionalità e sarai ok.