Here on the Performance team we support the functionality of the Windows Installer engine and the installation and uninstallation of .msi packages. We are also often engaged to help with issues by other teams when an installation fails to install (or uninstall). So today, we’re going to cover some basic concepts that we use when troubleshooting the Windows Installer engine as well as some useful tools.
There are two phases to every Windows Installer installation, Acquisition and Execution. If an installation is unsuccessful, then a rollback may occur. At the beginning of the acquisition phase a user instructs the installer to install a feature or component. The installer gets all of this information from the installation database (.msi). This is performed under the users context, referred to as client side. This information is used to generate a script that provides the installer with step-by-step instructions for performing the installation. We then enter the execution phase, the installer passes this information off to a process with elevated privileges and we run the script - referred to as the server side.
An equally important feature of the Windows Installer is the rollback. As I mentioned above if the installation is unsuccessful a rollback may occur. During the installation the installer keeps track of all the registry changes and files that are updated and it compiles those into a rollback script, so if the installation does fail we can put the machine back to its pre-existing configuration prior to executing this particular package. The benefit of this is that it allowed software vendors to reduce the ever growing "DLL Hell" that was a common problem with some older installation technologies.
So, let's dive right into troubleshooting a Windows Installer issue. This issue concerns a SQL 2005 SP2 installation on a Windows Server 2003 (64-bit). On this server, we'd noticed some random issues with this server in respect to the Windows Installer. When launching some applications the Installer would run and some applications wouldn’t uninstall but with this being a SQL server it didn’t become a real problem until it was time to apply the latest SQL service pack. The error that we got during the SQL Server service pack installation was pretty nondescript so we started by checking the basic functionality of the installer by attempting to uninstall an application from this server. When we tried to do this we were presented with the error message as shown.
The first thing that we want to do is check for any Windows Installer Event Logging. To learn more about Windows Installer Event Logging, check out this
MSDN Article on Event Logging
In this scenario, by checking the Application Event Log we see that we are getting an Event 1015 and the error code is 0x80040154 as shown below. Here’s where knowing what tool to use to extract the right data from the event will get us pointed in the right direction.
Using a tool call Error Lookup from the Visual Studio Tools (ERRLOOKUP.EXE), we can use some of the information from the Application Event log to help us in determine what are next steps are going to be. We want to take the error code from the error message "Failed to connect to server. Error: 0x80040154" and insert that into the Error Lookup tool and click "Look Up".
NOTE: You can also use the ERR.EXE utility included with the Windows Server 2003 Resource Kit to get the same information.
So the error message that we're getting is "Class not registered." With this little bit of information we know that our first step is to re-register the Windows Installer service. In this particular scenario we need to pay attention to the fact that we are performing this installation on 64-bit version of Windows. Thus, we need to make sure to register the Windows Installer engine (msiexec.exe) that resides in the \Windows\SysWOW64\ folder as well as the 64-bit version of the Windows Installer which resides in the \Windows\System32 folder.
Once we re-register the installer, we can then enable the Windows Installer Logging policy. This can be done from the Group Policy Snap-in (gpedit.msc). From within the snap-in, Local Computer Policy --> Computer Configuration --> Administrative Templates --> Windows Components --> Windows Installer --> Logging and add the values “
” (without the quotes). You can also add the logging policy by editing the registry directly per the instructions in
. Now that the server is prepared to generate a log file during the installation of SQL 2005 SP2 we can now launch the installation again and see what happens. During the installation of the Service Pack, installing the SQL Server Support Files we receive the following error:
We’ll want to take a look through the Windows Installer log that was generated; which is always generated in the logged on user’s \temp directory (%temp%):
=== Verbose logging started: 7/5/2007 10:04:57 Build type: SHIP UNICODE 3.01.4000.4042 Calling process: c:\8353cbfd29e082f755ad9957\hotfix.exe ===
MSI (c) (20:14) [10:04:57:494]: SOFTWARE RESTRICTION POLICY: Verifying package --> 'C:\WINDOWS\Installer\941ae4.msi' against software restriction policy
MSI (c) (20:14) [10:04:57:494]: Note: 1: 2262 2: DigitalSignature 3: -2147287038
MSI (c) (20:14) [10:04:57:494]: SOFTWARE RESTRICTION POLICY: C:\WINDOWS\Installer\941ae4.msi is not digitally signed
MSI (c) (20:14) [10:04:57:509]: SOFTWARE RESTRICTION POLICY: C:\WINDOWS\Installer\941ae4.msi is permitted to run at the 'unrestricted' authorization level.
MSI (c) (20:14) [10:05:27:572]: Failed to connect to server. Error: 0x80080005
At this point we need to make note of the "Failed to connect to server" error. This is a different error code than before, we can use the same tool mentioned earlier (Visual Studio Tools - Error Lookup) to get some more details on this.
So, from here we know the service is registered but fails during the execution of the installation of the .msi package. Since the windows installer logs aren’t giving us much to go on in this scenario we can use a different tool - Process Monitor. We covered Process Monitor
in a previous post
. When setting up Process Monitor you’ll want to set a filter for msiexec.exe to watch what’s going on behind the scenes during the service pack installation as shown in the image below:
Now that that’s all setup we can try the installation again. Looking at the msiexec.exe process we can see in the Process Monitor log files that we are getting ACCESS DENIED errors when trying to access HKEY_CLASSES_ROOT\Installer and HKEY_CLASSES_ROOT\CLSID:
Knowing that we are seeing ACCESS DENIED messages when trying to access the registry, the obvious thing to check is permissions. When we check the permissions in the registry on HKCR\Installer, we find that the SYSTEM account has DENY privileges and that it is an inherited permission (Figure 1).
After giving the SYSTEM account FULL CONTROL to HKCR (Figure 2) and allowing these permissions to propagate down through the remainder of the HKCR hive we’re ready to try the Service Pack installation again. At this point, we were able to successfully install SQL Server 2005 Service Pack 2.
That brings us to the end of this post. As you can see, sometimes it takes a variety of tools to accurately diagnose and troubleshoot Windows Installer issues.