Why does Windows Installer start installing some other product when I try to install or use a different MSI-based product?
I received a question in response to my blog entry about reverse engineering setup - basically the .NET Framework setup is being triggered while trying to install an unrelated product (in this case Drive Image 7). The details of this particular interation may not be interesting to everyone, but I think the underlying issue of why Windows Installer would start installing some other product when you try to install or use an unrelated product would make an interesting topic for discussion. I'm going to try to explain the underlying issue and also touch on some specific points related to the .NET Framework setup and how to fix it in particular.
This is a feature of Windows Installer called resiliency. Basically, what happens is that in various type of install or product usage scenarios, Windows Installer will query some or all of the products installed on the machine to determine if the features are correctly installed. If these queries return any kind of error code, Windows Installer will try to trigger a repair for the feature and product in question. This will appear as a small installation dialog with the name of the product in the title bar, and normally the text of the dialog will say something like "Configuring <product name>. Please wait...." and it will contain a progress bar and a cancel button.
In some resiliency repair scenarios, you will never be prompted for a source location. Windows Installer caches the original location that a product is installed from, and if it can be accessed during a repair it will seamlessly connect to that location and use the files from there. However, when this type of repair is triggered for the .NET Framework, another dialog will appear stating that Windows Installer could not find the original installation location and asks you to browse to the location of netfx.msi. This is because it is an IExpress setup package (explained further here), the original source location is no longer valid because IExpress creates a temporary folder in the %temp% folder on a machine, installs from there, and then deletes that folder. When any repair is triggered by Windows Installer, you will be prompted for the source location of the .NET Framework installation package (netfx.msi).
If you are prompted for the location of netfx.msi, you can extract it from dotnetfx.exe and then browse to that location. To do this, download dotnetfx.exe or locate it on your local hard drive or a CD. Then, from a cmd prompt run the following: dotnetfx.exe /t:c:\temp /c. You can substitute any folder you want for the "c:\temp" parameter. Once the extraction is complete, browse to the folder you provided for the /t argument and .NET Framework repair should complete with no further issues.
Identifying the Root Cause
Locating netfx.msi can help get you past the browse dialog that appears, but it does not really help answer the more important question - why is the repair being triggered in the first place? I have seen many cases where an incorrectly authored MSI setup package has inadvertantly triggered a repair for a product already installed on the machine. In order to diagnose the root cause of the repair request, I usually do the following:
- Go to the Start menu and run eventvwr.exe
- Locate the Application event log and click on it to list the events
- For each repair that was triggered, there will be an entry in this log with a source named MsiInstaller
- Using the GUID of the component or feature that is being repaired, it is usually possible to look at the MSI for the product in question using Orca and determine why Windows Installer thinks it needs to perform a repair
In most cases, you will need to have a pretty solid level of Windows Installer expertise to track down a root cause based on the application event log entries. It is also possible to export the application event log and send it to someone else (such as a Product Support specialist) for help diagnosing the problem. To do this, simply right-click on the application event log and choose Save Log File As... in the menu that appears. Then you can save the file as *.evt, and someone else can import it and view it using eventvwr.exe
Hope this helps explain things a little bit. Let me know if I got any of the above wrong or if you have any specific questions/comments....