Windows Installer Cache



Windows Installer packages may contain streams identified in the Media table if the Cabinet column value begins with the number sign #, as documented for the Cabinet data type. This cabinet is embedded as a stream within the .msi file and contains files referenced in the File table using their File key column value. When packages are installed, however, cabinet streams are stripped from the .msi file and the .msi file is copied to %WINDIR%\Installer. This saves a significant amount of space required for large packages that are installed on the machine; however, this is part of the reason for prompts for source when the original media isn’t available.

As documented in What’s in a Patch, patches may also contain embedded streams since .msp files use structured storage as do .msi files. When patches are applied to a product, however, the embedded cabinet streams are not stripped. This is necessary because of how patches are applied and how updated files are made available. The patched files’ Sequence column value is updated and a new Media table entry added for each patch being applied. This determines which cabinet stream to use by matching the DiskId column value of the Media table entry to the Media column value in the PatchPackage table. When the patched features are reinstalled the updated files are extracted from the correct patch and copied to the destination location (or to a temporary location to be later copied after a reboot).

For example, we will take a look at the differences between the source and cached .msi files for my Shell Extensions for .NET Assemblies, version 1.4.1993. With the Windows Installer SDK installed as part of the Platform SDK, we’ll need to invoke the WiStream.vbs script from the Samples\SysMgmt\Msi\Scripts directory under the Platfrom SDK installation root directory.

First WiStream.vbs is invoked with the AsmShell.msi file that was downloaded as the sole parameter and you’ll see the following:

Here ? is the character displayed for the octal number \005 which begins the \005SummaryInformation stream as it is displayed in the OEM code page 437 used by the console for U.S. English.

After AsmShell.msi is installed, we need to find the cached package under %WINDIR%\Installer.

Warning: Do not alter the Windows Installer internal information by hand. If you alter the Windows Installer internal information, you may cause serious problems that may require you to reinstall your operating system. Microsoft cannot guarantee that you can solve problems that result from altering the Windows Installer internal information. Alter the Windows Installer internal information at your own risk.

The names aren’t descriptive, so one way of finding the correct .msi file is to open the hidden %WINDIR%\Installer directory in Windows Explorer, change to the Details view, right-click on the columns, and add the Comments column. Find the file with the comment, “Windows Explorer Shell Extensions for .NET Assemblies”. Now invoke WiStream.vbs on that file and you’ll see the following:

Notice that _8FAD87CB641B23946B4BDE84517E0FCF is missing. If you look in the Media table for AsmShell.msi you’ll see that lone cabinet name is #_8FAD87CB641B23946B4BDE84517E0FCF, which is an embedded stream since it begins with the number sign #.

Now we will do the same with the patch referenced in Updated Sample MSI Scripts, which will allow WiStream.vbs and WiSubStg.vbs to work on .msp files which will be necessary for this next step. After installing the patch that applies to the Platform SDK we invoke WiStream.vbs on the Scripts.msp and will see the following output:

Next you’ll need to find the .msp file in %WINDIR%\Installer that has the revision number {F32C36B7-3547-4B1F-954F-FFED85EBDE92} which, for a patch, is the patch code. Invoking WiStream.vbs on that file yields the following output:

You’ll notice the cabinet stream that contains the patch files is present in both the source and cached .msp files.

Heath Stewart

Senior Software Engineer

Follow Heath   


    Leave a comment