Column Types Cannot be Changed in a Patch or Transform
Transforms can change just about anything in an installation package – even the code page. Transforms can also add and drop both tables and columns but they cannot, however, change the column type. This is true for patches as well, since a patch package contains transforms.
At their core, transforms store data aligned to the size of the data type. An i2 column – a SHORT, INT, or INTEGER in the column definition format – stores 16 bits of data while an i4 column – a LONG – stores 32 bits of data. If a product, for example, defines the File table’s Sequence column as i2 and a patch updates the Sequence column type to i4 then the data in the patch transform will be misaligned.
When applying the transform or patch, the installation will fail. Windows Installer 4.0 and newer handle this failure gracefully by posting Windows Installer error message 2247 and returning error ERROR_PATCH_PACKAGE_INVALID (1636). Windows Installer 3.1 and older will throw an access violation exception.
The best approach if you need to change the column type for a product that has already shipped is to ship a new small update or minor upgrade .msi package and re-cache it when reinstalling. This is a full product install but will still follow much of the same behavior as a patch when it comes to updating component resources. The key is that the REINSTALLMODE property contains “v” in its value to copy the new, updated .msi package to the cache. Future maintenance installations can then take advantage of the updated column types. You can also use a major upgrade that removes the existing product. This is a new product install – not a reinstall – and is cached automatically like any other new product install.
If you plan on using the new msidbCustomActionTypePatchUninstall (0x8000) custom action attribute introduced in Windows Installer 4.5 you will need to update the CustomAction table’s Type column to i4. Note that ICE validation will fail for ICE03 if you don’t update the _Validation table, and for ICE45 with these new bits set when using older .cub files. When new .cub files are made available for Windows Installer 4.5 you should validate against them.
There is some protection against this problem when generating patches.
When the schemas of the target and upgrade databases differ, PatchWiz.dll will return an error. PatchWiz.dll 3.1 and older simply log that the authoring transform couldn’t be created. PatchWiz.dll 4.0 and newer is more helpful, logging both the return code from MsiDatabaseGenerateTransform as ERROR_INSTALL_TRANSFORM_FAILURE (1624) and the last error record, message 2248, which explicitly states that a specific column’s type differ between the target and upgrade databases. In both cases, UiCreatePatchPackage and UiCreatePatchPackageEx (available in PatchWiz.dll 4.0 and newer) – assuming no errors occur during clean-up – return ERROR_PCW_CANT_GENERATE_TRANSFORM (0xC00E5173, 3222163827).
In WiX 3.0.3210.0 support was added for generating a patch from two administrative installations. Currently, if the target or upgrade database schemas differ from the internal table definitions in WiX, a transform will be generated against the internal schema so that the transform builds successfully but will not apply, nor will a patch containing that transform apply, to the target product. It is recommended, therefore, to use the same version of WiX that was used to build the product or use the existing PatchCreation element in WiX to generate a .pcp file that can be used with PatchWiz.dll from the Windows Installer SDK. You can use msimsp.exe also in the SDK as a wrapper around PatchWiz.dll. The topic “Using Patch Creation Properties” in wix.chm has more details and instructions.