Wix/MSI and unique per-installation directory

Viewed 43

Is it possible to install files from an MSI in a unique per-installation directory? For example, I would like to do the equivalent of the following:

<Directory Id="TARGETDIR" Name="SourceDir">
    <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLDIR" Name="$(var.MyProductName)">
            <Directory Id="SXSBASEDIR" Name="SxS">
                <Directory Id="SXSDIR" Name="<<Unique-ID>>">
                                                   ^
                                                   |
---------- Notice the <<Unique-ID>> here ----------+

                    <Directory Id="BINDIR" Name="bin" />
                </Directory>
            </Directory>
        </Directory>
    </Directory>
</Directory>

The <<Unique-ID>> must be different for every installation. For example, if one installs the MSI once, files end up installed in \Program Files\MyProductName\SxS\<<Unique-ID-1>>\bin. If then one uninstalls and then reinstalls the same MSI, files should end up installed in \Program Files\MyProductName\SxS\<<Unique-ID-2>>\bin.

I have looked at DATE and TIME variables as a means to generate the <<Unique-ID>> but unfortunately they contain characters that are not legal in file names (and their format varies according to locale). Any suggestions on how to approach this are appreciated. If the only answer is to use a custom action, where in the InstallExecuteSequence would you recommend that I place the custom action?

EXPLANATION

An explanation of why I need this follows.

I have a Windows file system driver (FSD) which is a kernel mode driver. Due to Windows file system design once an FSD is loaded it cannot be (easily) unloaded. This makes uninstallation and upgrades impossible without a system reboot.

As a workaround I have come up with a solution where the FSD is installed in a unique per-installation directory, for example: \Program Files\MyProductName\SxS\<<Unique-ID>>\bin. This should allow for multiple instances of the FSD to be loaded at the same time, the currently installed one and any previously uninstalled ones. (The FSD has already been modified to support such side-by-side operation.)

Consider, for example, the following scenario:

  • User installs MyProduceName.msi.

    • The FSD is installed in \Program Files\MyProductName\SxS\1\bin.
  • The FSD is loaded and is potentially unloadable (for reasons outside of the scope of this discussion).

  • User uninstalls MyProductName.msi.

    • The Windows installer infrastructure marks the \Program Files\MyProductName\SxS\1\bin as deleted but the directory remains.
  • User reinstalls the same MyProductName.msi.

    • The FSD is installed in \Program Files\MyProductName\SxS\2\bin.
  • The FSD is loaded again.

  • At this point two instances of the same FSD exist:

    • The originally installed FSD, which will go away after a reboot. This FSD location is in the directory \Program Files\MyProductName\SxS\1\bin which is marked as deleted and will go away after a reboot.

    • The currently installed FSD. This FSD location is in the directory \Program Files\MyProductName\SxS\2\bin and will remain after a reboot.

1 Answers

You need to write a custom action e.g a vbscript which will set the string using some random number and then INSTALLDIR could be be set.

dim r
randomize
r = int(rnd*10) + 1
session.TargetPath("INSTALLDIR") = session.property("ROOTDRIVE") + '\Program Files\SxS\' + r + '\bin'

This custom action should be sequenced after CostFinalize action.

Related