0
votes

Our installer uses a CustomAction (invoked in the InstallExecuteSequence) to optionally copy user configuration files from a directory next to the installer. This uses [SourceDir] to locate the source directory.

We currently have 32-bit and 64-bit versions which are distributed as separate .MSI files. I'm attempting to use Burn to build a single .EXE containing these .MSI files. Obviously when an MSI is installed by Burn, its [SourceDir] is somewhere else (I'm seeing C:\ProgramData\Package Cache\... paths) so this custom action doesn't work.

I've found the WixBundleOriginalSource variable, but my problem is that I want the MSI files to work in isolation AND when packaged with Burn. I think I need to set a variable conditionally to WixBundleOriginalSource if it's defined (user installing with Burn .exe) or to SourceDir if WixBundleOriginalSource isn't defined (user installing .MSI directly) and then pass this variable to my custom action. (I'm aware that WixOriginalSource is the full path of the installer, not the directory that it's located in - I can deal with that in my custom action.)

Is this possible? If so, please can you help me with the syntax.

Update:

I could potentially handle the conditional part in my custom action, and call it twice: once with [SourceDir] (which works when the MSI is used directly), as I'm doing now:

in my Product

    <CustomAction Id='CopyConfigFiles'
                  FileKey="MyInstallationUtility"
                  ExeCommand="COPYFILES [SourceDir]"
                  Execute="deferred"
                  Impersonate="no"
                  Return="ignore" />

... and once with WixBundleOriginalSource. However, I can't find a way to get WixBundleOriginalSource to me custom action. Using:

                  ExeCommand="COPYFILES [WixBundleOriginalSource]"

... doesn't work. Using:

In my Burn Bundle

    <WixVariable Id="ConfigFileLocation" Value="[WixBundleOriginalSource]" />

and in my Product

                  ExeCommand="COPYFILES [ConfigFileLocation]"

... also doesn't work. Both give me an empty string as the parameter.

1
The answer to this question would appear to answer my last question: stackoverflow.com/questions/17729878/…davidm_uk

1 Answers

6
votes

The solution is to define a Property in the MSI script which can be overridden by burn, and make the MSI script set it to [SourceDir] if burn doesn't set it.

In the MSI script we define the property (initialising it to a 'unset' which we test for later) and a custom action to set it to [SourceDir]:

    <Property Id='CONFIGFILELOCATION' Value='unset' />
    <CustomAction Id='MsiConfigLoc' Property='CONFIGFILELOCATION' Value='[SourceDir]' Execute='immediate' />

The custom action that needs the installer's location is updated to use this new property:

<CustomAction Id='CopyConfigFiles'
              FileKey="MyInstallationUtility"
              ExeCommand="COPYFILES [CONFIGFILELOCATION]"
              Execute="deferred"
              Impersonate="no"
              Return="ignore" />

The InstallExecuteSequence is then extended to call the new custom action (before CopyConfigFiles) conditionally - only if CONFIGFILELOCATION hasn't been set by the burn EXE:

        <Custom Action='MsiConfigLoc' Before='CopyConfigFiles'>CONFIGFILELOCATION="unset"</Custom>
        <Custom Action='CopyConfigFiles' Before='InstallFinalize'/>

Finally, in the Burn Bundle we set the CONFIGFILELOCATION property to [WixBundleOriginalSource]:

        <MsiPackage SourceFile='ProductSetup.msi' DisplayInternalUI='yes'>
            <MsiProperty Name='CONFIGFILELOCATION' Value='[WixBundleOriginalSource]' />
        </MsiPackage>

From WiX 3.9 it would be better to use [WixBundleOriginalSourceFolder] as this gives the directory in which the installer executable is in. I'm using [WixBundleOriginalSource] here (the full path of the installer executable) and dealing with stripping off the filename in my custom installation code.