WiX - 如何在安装时设置合并模块目录?

3
我已经按照Wix入门指南上的说明创建了一个合并模块,该指南位于以下网址:http://wix.sourceforge.net/manual-wix2/authoring_merge_modules.htm
下面是合并模块的wxs代码:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Module Id="SomeRepositoryMergeModule" Language="1033" Version="1.0.0.0">
    <Package Id="f11e7321-a687-4d53-8be7-21a8ae0721a6" Manufacturer="SomeCompany Technologies" InstallerVersion="200" />

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
          <Directory Id="MODULEINSTALLLOCATION" Name="Some Repository">
            <Component Id="ServicesHostWindowsService" Guid="257D1FAE-4AFF-4155-BDB8-D81F50E5862B">
              <File Id="ServicesHostInstallerExecutable" KeyPath="yes" DiskId="1" Name="WindowsServiceHost.exe" Source="..\WindowsServiceHost\bin\Output_For_Installer\WindowsServiceHost.exe" />
              <File Id="ServicesHostConfig" KeyPath="no" DiskId="1" Name="WindowsServiceHost.exe.config" Source="..\WindowsServiceHost\bin\Output_For_Installer\WindowsServiceHost.exe.config" />
              <File Id="SomeCompanyCommon" KeyPath="no" DiskId="1" Name="SomeCompany.Common.dll" Source="..\WindowsServiceHost\bin\Output_For_Installer\SomeCompany.Common.dll" />
              <File Id="SomeRepositorySqlScript" KeyPath="no" DiskId="1" Name="SomeRepository.sql" Source="..\..\..\..\..\DB\SomeRepository\SomeRepository.sql" />
              <File Id="LogConfigXml" KeyPath="no" DiskId="1" Name="log.config.xml" Source="..\WindowsService\log.config.xml" />
              <ServiceInstall Id="ServicesHostInstallElement" ErrorControl="normal" Start="auto" Type="ownProcess" Vital="yes"
                              Name="AServer WindowsService Host"
                              Description="The windows service responsible for hosting SomeCompany Some Repository's WindowsService."
                                                    />
              <ServiceControl Id="ServicesHostController" Name="AServer WindowsService Host" Remove="uninstall" Start="install" Stop="uninstall" Wait="no" />
            </Component>
          </Directory>
      </Directory>
    </Directory>
    <ComponentGroupRef Id="Product.Generated" /><!-- Harvested by heat -->
  </Module>  
</Wix>

这里是主要的产品wxs:
    <Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

<Directory Id="TARGETDIR" Name="SourceDir">
  <Directory Id="ProgramFilesFolder">
    <Directory Id="SomeCompanyGlobalDir" Name="SomeCompany Technologies">
      <Directory Id="INSTALLLOCATION" Name="Some Repository">
        <Merge Id='SomeRepositoryPrimaryModule' Language='1033' SourceFile='..\SomeRepositoryMergeModule\bin\Output_For_Installer\SomeRepositoryMergeModule.msm' DiskId='1' />          
      </Directory>
    </Directory>
  </Directory>
</Directory>

<Feature Id="ProductFeature" Title="SomeRepositoryStandaloneInstaller" Level="1">           
  <!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. -->            
  <MergeRef Id="SomeRepositoryPrimaryModule"/>
</Feature>

<UIRef Id="WixUI_InstallDir" />
<UIRef Id="WixUI_ErrorProgressText" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />

当我构建安装程序并运行它时,合并模块中的文件不会进入用户在安装程序界面中选择的目录。无论如何,它们都会进入"[Program Files]\SomeCompany Technologies\Some Repository\"目录。
如果我从合并模块目录路径中删除对Program Files的引用,并使用一个名为"."的根目录来获取父MSI的父目录,则合并模块可以很好地获取用户选择的目录。但是,Visual Studio在构建时会抛出错误,因为收集工具必须以标准目录之一为根目录才能使用自动生成的GUID。
那么,我怎样才能使合并模块在保持根目录为标准目录的同时,采用用户在安装时选择的目录呢?

顺便说一下,我尝试将ConfigurableDirectory添加到Feature标记中,并将值设置为INSTALLLOCATION,但它仍然无法获取目录... - Ayo I
1个回答

6
你正在使MSI困惑,因为ProgramFilesFolder是一个保留的属性名。将该值更改为"MergeRedirectFolder",并通过具有Id INSTALLLOCATION的Directory元素下的Merge元素的优势,MergeRedirectFolder将与INSTALLLOCATION相关联。然后,目录"Some Repository ([MODULEINSTALLLOCATION])"将成为INSTALLLOCATION的子目录。
此外,随时可以在CodePlex上检查ISWIX项目。它对于编写和维护合并模块很有用,并且具有与您在此处尝试做的相关的示例源代码。

没错,但是由于收割问题,我无法应用您之前提供的解决方案。我试图验证您的解决方案,但无法完成,因为Visual Studio/heat似乎认为将ProgramFilesFolder替换为MergeRedirectFolder会使组件在标准目录中没有根。 - Ayo I
2
就我所知,我基本上反对"收割"。当你让计算机在构建时找出你的依赖关系并为你编写它们时,可能会出现很多问题,而不是让你自己做,并且只有在你想要改变它时才会发生变化。 - Christopher Painter
谢谢。非常好的回应,正是我所需要的。 - Tom Beech
@user497745 你解决了这个问题吗?虽然我没有进行收割,但我遇到了你在评论中描述的同样问题。 - sirdank
我还没有使用过收割,但或许这会有所帮助。我不得不在我的顶级<Directory>元素中添加 ComponentGuidGenerationSeed="{GUID-GOES-HERE}"。我相信在主要升级时我仍然需要更改它,但更改一个GUID比手动硬编码每个组件以具有唯一的GUID要好得多。 - sirdank
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接