WiX - Set Merge Module Directory at Install Time?

6.4k views Asked by At

I've created a merge module following the instructions in the Getting Started Wix guide located at: http://wix.sourceforge.net/manual-wix2/authoring_merge_modules.htm.

Here is the merge module 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>

And here is the main product 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" />

When I build the installer and run it, the files from the merge module are not going into the directory selected by the user from within the installer UI. No matter what, they go into the "[Program Files]\SomeCompany Technologies\Some Repository\" directory.

If I remove the reference to Program Files from the merge module directory path and use a root dir with a name of "." to pick up the parent directory of the parent MSI then the merge module picks up the user selected directory just fine. But then Visual Studio throws an error on build that harvesting won't work because the path must be rooted in one of the standard directories in order to use automatically generated Guids.

So how can I get the merge module to take the directory selected by the user at install time while still keeping the merge module path rooted in a standard directory?

1

There are 1 answers

8
Christopher Painter On BEST ANSWER

You are confusing MSI because ProgramFilesFolder is a reserved property name. Change that value to "MergeRedirectFolder" and by virtue of the Merge element under the Directory element with Id of INSTALLLOCATION MergeRedirectFolder will become associated with INSTALLLOCATION. The directory Some Repository ([MODULEINSTALLLOCATION]) will then be a subdirectory of INSTALLLOCATION.

Also feel free to checkout the ISWIX project on CodePlex. It's useful for authoring and maintaining merge modules and has sample source code relevant to what you are trying to do here.