The TARGETDIR property, paired with the SourceDir property in the Directory table, determines the root directory into which all files are copied unless otherwise located. During an administrative installation when all files are extracted the TARGETDIR, this is the only root directory on the file system. The directory structure in the Directory table without any redirection like that resulting from expanding ProgramFilesFolder is used as-is.
During installation, however, a number of things affect the location of components. Often, a directory structure is built under ProgramFilesFolder and TARGETDIR is forgotten or ignored because system folders like ProgramFilesFolder would already be set correctly. When TARGETDIR is not set, however, Windows Installer sets TARGETDIR to ROOTDRIVE, which is set to fixed drive with the most free space available. This may not be the drive where other files are installed, likely resulting in incorrect application behavior.
Evidence of this can be seen in Visual Studio 2005 and older Office SKUs where Dr. Watson files would be installed to a directory structure similar to that found on the drive you actually choose for the install location. That is, if you choose to install to your C: drive but your fixed D: drive had more free space available, some files would be installed to your D: drive.
To help avoid these issues in Visual Studio 2008 we run a custom ICE. Some registry-only components are installing to TARGETDIR since they contain no files, but we require that the KeyPath in the Component table be set to a registry row ID and that the component is attributed accordingly. Other component that are installing files to TARGETDIR or descendents of TARGETDIR must find an existing, more suitable directory or schedule a type 51 custom action.
While building the structure using only the Directory table is best, some scenarios where install locations are not known at build time require install-time redirection. Type 51 custom actions are recommended to either set TARGETDIR or any other directory (treated as a property) if scheduled before CostFinalize. The Setup projects in Visual Studio use a type 51 CA to actually set TARGETDIR, and the CA is attributed with msidbCustomActionTypeFirstSequence (256) to make sure it is only set once if not overridden on the command line using the format [ProgramFilesFolder][Manufacturer][ProductName].
If a directory is not known until after file costing, you must use a type 35 custom action scheduled after CostFinalize. Type 35 CAs can be tricky to use, however, and should be conditioned to run only when a component is transitioning from the Absent state to Local or Source, or between Local and Source states. Ideally, this means you have one type 35 CA authored for each component that requires it. If you don’t have the resources for that much authoring, fall back to using feature states in the same manner; or if the components are always installed you can condition type 35 CAs using “NOT Installed” to only be executed during initial installation of both the products and affected components.
0 comments