我的产品包含多个功能,可以安装到不同的位置,例如功能1是安装在程序文件中的可执行文件,功能2是安装在wwwroot中的网站。但是,Feature 1和Feature 2都依赖于许多相同的dll,因此需要将包含这些dll的组件安装在2个不同的位置,具体取决于安装的功能。
有没有办法在不定义每个组件两次的情况下实现这一目标?
为了提供我想要实现的更完整的示例,可以使用以下代码编译以下完整的wxs文件:
> 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>
然而,这将导致仅在
中安装File1.txtC:\ 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多个组件,管理重复组件将成为一项重要工作。
有什么建议吗?
答案 0 :(得分:14)
您看到Windows Installer存在限制。组件只能通过MSI安装一次。每个组件只能安装到一个目录中。要将组件的内容安装到两个不同的位置,您必须创建具有相同内容的另一个组件,或者尝试使用CopyFile元素复制内容。
可能不是您想听到的内容,但这是Windows Installer的工作方式。
幸运的是,如果您选择使用选项1,那么WiX工具集将仅压缩组件中的重复内容一次。 Smart cabbing rocks!
答案 1 :(得分:1)
我建议创建一个仅包含常用组件的单独功能。它不应该默认安装。然后,您可以创建自定义操作,仅在安装了某个实际功能时才标记此功能。
要标记要安装的功能,可以使用MsiSetFeatureState函数: http://msdn.microsoft.com/en-us/library/aa370387(VS.85).aspx
执行此操作的自定义操作可以通过功能的功能操作来调节: http://msdn.microsoft.com/en-us/library/aa368561(VS.85).aspx
答案 2 :(得分:0)
功能可以引用浏览功能的目录,但这仅仅意味着组件使用该目录的目录或该目录的子目录。否则,组件将转到指定的目录。换句话说,你可以拥有该功能的INSTALLDIR,而且大多数组件都有ANOTHERDIR(比如[CommonFilesFolder] Company \ Shared为另一个组件而且它会去那里。那个组件可以属于多个功能,你就可以了。< / p>