Rebuilding the Installer Cache

Heath Stewart

During some operations upgrades internally, a problem arose on some machines where a patch for the Microsoft .NET Framework 2.0 would fail to install. I was looped into the thread to diagnose the issue and found that the Windows Installer package and the patch package were both missing from the installer cache. Since a .msp file is just a container for transforms and files that apply to a .msi file, the .msi file must exist in order to be transformed and reinstalled. Any patches that are registered from previous installs must also exist, so when any of these files are missing it is a big problem.

While only a couple of machines out of many exhibited this problem, it raised questions about why those files were missing. Windows Installer will clean-out the installer cache if ever the owner on the %WINDIR%Installer directory changes from SYSTEM or Administrators, so that is one likely cause. Perhaps a security template tried to “tighten” security. This does, however, yield a good opportunity to show how important verbose logs are when performing any Windows Installer action, as well as showing how source resolution works.

Remember that to generate verbose logs, pass “/L*v <file name>” (without quotes) to the command line for msiexec.exe. If using Windows Installer 3.0 or newer, you can also pass “x” along with “*v” to the logging switch for additional debug information.

Take a look at the following rather long log snippet, with some portions highlighted for easy reference throughout the rest of this post.

******* Product: {B6EC01E7-431D-4D29-B9D4-E1D74CAF0AB0}
******* Action:
******* CommandLine: **********
MSI (c) (DC:10) [19:14:38:575]: Machine policy value ‘DisableUserInstalls’ is 0
MSI (c) (DC:10) [19:14:38:575]: Warning: Local cached package ‘C:WINDOWSInstaller478d2c9.msi’ is missing.
MSI (c) (DC:10) [19:14:38:606]: User policy value ‘SearchOrder’ is ‘nmu’
MSI (c) (DC:10) [19:14:38:606]: User policy value ‘DisableMedia’ is 0
MSI (c) (DC:10) [19:14:38:606]: Machine policy value ‘AllowLockdownMedia’ is 0
MSI (c) (DC:10) [19:14:38:606]: SOURCEMGMT: Media enabled only if package is safe.
MSI (c) (DC:10) [19:14:38:606]: SOURCEMGMT: Looking for sourcelist for product {B6EC01E7-431D-4D29-B9D4-E1D74CAF0AB0}
MSI (c) (DC:10) [19:14:38:606]: SOURCEMGMT: Adding {B6EC01E7-431D-4D29-B9D4-E1D74CAF0AB0}; to potential sourcelist list (pcode;disk;relpath).
MSI (c) (DC:10) [19:14:38:622]: SOURCEMGMT: Now checking product {B6EC01E7-431D-4D29-B9D4-E1D74CAF0AB0}
MSI (c) (DC:10) [19:14:38:622]: SOURCEMGMT: Media is enabled for product.
MSI (c) (DC:10) [19:14:38:622]: SOURCEMGMT: Attempting to use LastUsedSource from source list.
MSI (c) (DC:10) [19:14:38:638]: SOURCEMGMT: Trying source C:WINDOWSMicrosoft.NETFramework64v2.0.50727Microsoft .NET Framework 2.0 (x64).
MSI (c) (DC:10) [19:14:39:263]: Cloaking enabled.
MSI (c) (DC:10) [19:14:39:263]: Attempting to enable all disabled priveleges before calling Install on Server
MSI (c) (DC:10) [19:14:39:310]: SOURCEMGMT: Resolved source to: ‘C:WINDOWSMicrosoft.NETFramework64v2.0.50727Microsoft .NET Framework 2.0 (x64)’
MSI (c) (DC:10) [19:14:40:403]: SOFTWARE RESTRICTION POLICY: Verifying package –> ‘C:WINDOWSMicrosoft.NETFramework64v2.0.50727Microsoft .NET Framework 2.0 (x64)netfx.msi’ against software restriction policy
MSI (c) (DC:10) [19:14:40:403]: SOFTWARE RESTRICTION POLICY: C:WINDOWSMicrosoft.NETFramework64v2.0.50727Microsoft .NET Framework 2.0 (x64)netfx.msi has a digital signature
MSI (c) (DC:10) [19:14:40:419]: SOFTWARE RESTRICTION POLICY: C:WINDOWSMicrosoft.NETFramework64v2.0.50727Microsoft .NET Framework 2.0 (x64)netfx.msi is permitted to run at the ‘unrestricted’ authorization level.
MSI (c) (DC:10) [19:14:40:419]: Cloaking enabled.
MSI (c) (DC:10) [19:14:40:419]: Attempting to enable all disabled priveleges before calling Install on Server
MSI (c) (DC:10) [19:14:40:419]: End dialog not enabled
MSI (c) (DC:10) [19:14:40:419]: Original package ==> C:WINDOWSMicrosoft.NETFramework64v2.0.50727Microsoft .NET Framework 2.0 (x64)netfx.msi
MSI (c) (DC:10) [19:14:40:419]: Package we’re running from ==> C:DOCUME~1th871LOCALS~1Temp1b4d214b.msi
MSI (c) (DC:10) [19:14:40:466]: APPCOMPAT: looking for appcompat database entry with ProductCode ‘{B6EC01E7-431D-4D29-B9D4-E1D74CAF0AB0}’.
MSI (c) (DC:10) [19:14:40:466]: APPCOMPAT: no matching ProductCode found in database.
MSI (c) (DC:10) [19:14:40:482]: MSCOREE not loaded loading copy from system32
MSI (c) (DC:10) [19:14:40:607]: Opening existing patch ‘C:WINDOWSInstallera4784a.msp’.
MSI (c) (DC:10) [19:14:40:607]: Note: 1: 2203 2: C:WINDOWSInstallera4784a.msp 3: -2147287038
MSI (c) (DC:10) [19:14:40:607]: Couldn’t find local patch ‘C:WINDOWSInstallera4784a.msp’. Looking for it at its source.

MSI (c) (DC:10) [19:14:40:607]: Resolving Patch source.
MSI (c) (DC:10) [19:14:40:607]: User policy value ‘SearchOrder’ is ‘nmu’
MSI (c) (DC:10) [19:14:40:607]: SOURCEMGMT: Media enabled only if package is safe.
MSI (c) (DC:10) [19:14:40:607]: SOURCEMGMT: Looking for sourcelist for product {76112B23-E8BF-4307-9638-9C1A22692A65}
MSI (c) (DC:10) [19:14:40:607]: SOURCEMGMT: Adding {76112B23-E8BF-4307-9638-9C1A22692A65}; to potential sourcelist list (pcode;disk;relpath).
MSI (c) (DC:10) [19:14:40:607]: SOURCEMGMT: Now checking product {76112B23-E8BF-4307-9638-9C1A22692A65}
MSI (c) (DC:10) [19:14:40:607]: SOURCEMGMT: Media is enabled for product.
MSI (c) (DC:10) [19:14:40:607]: SOURCEMGMT: Attempting to use LastUsedSource from source list.
MSI (c) (DC:10) [19:14:40:607]: SOURCEMGMT: Trying source C:DOCUME~1th871LOCALS~1Temp1ZNW1.
MSI (c) (DC:10) [19:14:40:607]: Note: 1: 2203 2: C:DOCUME~1th871LOCALS~1Temp1ZNW1NDP20-KB913393-X64.msp 3: -2147287037
MSI (c) (DC:10) [19:14:40:607]: SOURCEMGMT: Source is invalid due to missing/inaccessible package.
MSI (c) (DC:10) [19:14:40:607]: Note: 1: 1706 2: -2147483647 3: NDP20-KB913393-X64.msp
MSI (c) (DC:10) [19:14:40:607]: SOURCEMGMT: Processing net source list.
MSI (c) (DC:10) [19:14:40:607]: Note: 1: 1706 2: -2147483647 3: NDP20-KB913393-X64.msp
MSI (c) (DC:10) [19:14:40:607]: SOURCEMGMT: Processing media source list.
MSI (c) (DC:10) [19:14:41:685]: SOURCEMGMT: Resolved source to: ‘NDP20-KB913393-X64.msp’
MSI (c) (DC:10) [19:14:42:107]: Note: 1: 1314 2: NDP20-KB913393-X64.msp
MSI (c) (DC:10) [19:14:42:107]: Unable to create a temp copy of patch ‘NDP20-KB913393-X64.msp’.

In the log is all information necessary to rebuild the cache if needed. Uninstalling the product will not work because the .msp file is unavailable, and since the patch is registered to the product you will need any patches as well. Also note that the .msi file source location was resolved in this example only because .NET 2.0 caches its source in its entirety. Only a few products do this, such as .NET 2.0 and the Visual Studio 2005 Express SKUs because of their relatively small size. Caching RTM sources on disk for larger SKUs like Visual Studio 2005 Professional and Visual Studio 2005 Team Suite isn’t feasible, though the .msi file itself is cached.

If this problem occurred and a local source cache isn’t available, you can find the .msi file name so you can copy the original .msi file to that location – and it doesn’t have to be stripped of embedded cabinets. In this log, that location is C:WINDOWSInstaller478d2c9.msi.

Next, Windows Installer will look for any registered patches for that product. In this log there is one patch already installed, and Windows Installer is looking for C:WINDOWSInstallera4784a.msp. You can typically find out what patch you need to download or otherwise obtain by looking at the following source resolution log lines. In this log, you see that Windows Installer is checking the temporary client source location which includes the file name, NDP20-KB913393-X64.msp. Because of Microsoft’s naming conventions for sustained engineering, you know you need to download the patch for KB913393. From us you’ll actually download a .exe file, but you can pass “/extract” on the command to extract the .msp file and copy it to, in this example, C:WINDOWSInstallera4784a.msp.

Source resolution in Windows Installer can tell you a lot about locations of files. Many of the operation codes between InstallInitialize and InstallFinalize will also tell you a lot about the installation process, from where source for files are located as well as where files are being cached in the baseline cache. This is one of countless reasons you should always enable verbose logging – whether using a system policy or on the command line – when performing actions with Windows Installer. Provided that Windows Installer rolls back a failed install to leave the system in its previous state, little else is left to help diagnose the reason why the install action failed.

0 comments

Discussion is closed.

Feedback usabilla icon