A while back, I posted some instructions for using a tool from the Windows Resource Kit named SubInAcl that can be used to update file, folder and registry permissions. This tool can help fix some types of access denied errors that can be encountered while trying to install products, hotfixes and service packs on Windows.

Since that original post, I have heard from some people who have run into various types of problems while attempting to install and use the SubInAcl tool. I wanted to post more details about a few of these scenarios in case other folks run into similar issues in the future.

The reason for this error is that on some non-English operating systems, the name of the Administrators group is translated into the OS language. If you are running SubInAcl on a non-English OS where the name of the Administrators group is translated, you will need to update each of the command lines for SubInAcl to specify the translated name of the Administrators group.

Issue 2 - SubInAcl.msi fails to install

I have heard from a few people who were not able to get the SubInAcl.msi installer to work correctly on their systems, which prevented them from being able to use the tool. If you run into an error while installing SubInAcl.msi to install this tool, you can get a copy of the tool that does not require a full installation from an alternate location by using the following steps:

Note - you should first attempt to install and run SubInAcl.msi before downloading and extracting this zip file. This zip file is only intended for cases where for some reason, SubInAcl.msi will not install correctly - which unfortunately can sometimes happen because of one of the same issues that SubInAcl is designed to fix.

Issue 3 - How to get SubInAcl to create a log file

SubInAcl is a console application, which means that the output that it prints will be displayed in the console window by default. For the command lines listed in my previous blog post, SubInAcl prints a lot of information, and if any errors occur, it will quickly scroll off the screen and you won't be able to see the details of the errors.

For a console application like SubInAcl, running it from a cmd prompt and putting a greater than sign and then the name of a file at the end of the command line (such as > %temp%\subinacl_output.txt) will cause the output to be redirected to a file. I recently updated the command lines in that post and in the example script I posted on my file server to use this syntax to redirect the output to a file instead of printing it to the console.

Note - creating a log file as described above will not work if you run SubInAcl from the Windows start menu. It has to be run from a cmd prompt in order to allow the log file to be created.

<update date="3/30/2009"> Fixed broken download links that are contained in this post. </update>

<update date="10/7/2014"> Added a note to the top of this post with alternate instructions for people who were referred to this blog post from this knowledge base article. </update>

Recently, I heard from a customer who could not get the .NET Framework 2.0 SP1 to install correctly on their system, and I wanted to explain the issue and how we were eventually able to resolve it in case anyone else runs into a similar issue in the future.

This error dialog is obviously not very helpful, and to complicate matters, there are not any errors reported in the .NET Framework 2.0 SP1 log files that are created in this scenario. I had the customer use these steps to gather a list of installed products, and it did not list the .NET Framework 2.0 SP1, and the information in the application event log seemed to indicate that setup had not even attempted to install the 2.0 SP1 MSI.

Root cause of this issue for the .NET Framework 2.0 SP1

Eventually I discovered that there was an orphaned registry value on the system that was causing .NET Framework 2.0 SP1 setup to get confused and think that the product was already installed, even though the MSI was not actually installed on the system. Once I discovered this issue, I was able to reproduce it on my test machine. This is the exact registry value that causes this issue during .NET Framework 2.0 SP1 setup:

While investigating this issue, I found that a similar issue can affect the installer for the .NET Framework 3.0 SP1. A similar dialog to the one shown above will appear when attempting to run .NET Framework 3.0 SP1 setup, and like in the case of the .NET Framework 2.0 SP1, no errors are reported in the .NET Framework 3.0 SP1 setup log files. This is the exact registry value that causes this issue during .NET Framework 3.0 SP1 setup:

Try again to download and install the .NET Framework 3.0 SP1 from this location

Root cause of this issue for the .NET Framework 3.5

The above issue can also affect the installer for the .NET Framework 3.5 because it uses the same setup engine as the .NET Framework 2.0 SP1 and 3.0 SP1. A similar dialog to the one shown above will appear when attempting to run .NET Framework 3.5 setup, and like in the cases above, no errors are reported in the .NET Framework 3.5 setup log files. This is the exact registry value that causes this issue during .NET Framework 3.5 setup:

Try again to download and install the .NET Framework 3.5 from this location

Another note about .NET Framework 3.5 setup

The above issues affects the standalone setup packages for the .NET Framework 2.0 SP1, the .NET Framework 3.0 SP1 and the .NET Framework 3.5. However, since the 2.0 SP1 and 3.0 SP1 packages are also installed as prerequisites by .NET Framework 3.5 setup, that means this issue can also cause a different type of failure during .NET Framework 3.5 setup than the one described above.

The orphaned registry value issue is specific to the MSI-based versions of the .NET Framework 2.0 SP1 and 3.0 SP1, so it is only possible to see the problem below during .NET Framework 3.5 setup on Windows XP and Windows Server 2003 since those are the only OS's that you can install the MSI-based versions of the .NET Framework 2.0 SP1 and 3.0 SP1 on (as described here).

If the orphaned registry key is from .NET Framework 2.0 SP1 or 3.0 SP1 setup (as opposed to from 3.5 setup), then the behavior of .NET Framework 3.5 setup is a bit different than the behavior for the standalone .NET Framework 2.0 SP1 and 3.0 SP1 setups described above. During .NET Framework 3.5 setup, an orphaned .NET Framework 2.0 SP1 or 3.0 SP1 registry value will cause an error dialog like the following will appear:

This is a generic error page that appears for all .NET Framework 3.5 installation failures. In this orphaned registry value scenario, the error log that appears when clicking the link in this dialog displays misleading information about the cause of the failure. If the system has the .NET Framework 2.0 SP1 registry value orphaned, the .NET Framework 3.5 setup error log will indicate that the .NET Framework 3.0 SP1 is failing. If the system has the .NET Framework 3.0 SP1 registry value orphaned, the .NET Framework 3.5 setup error log will indicate that the .NET Framework 3.5 is failing like in the following log snippet:

However, if you look in the main install log file for .NET Framework 3.5 setup (%temp%\dd_dotnetfx35install.txt), you will not see any attempt to install the .NET Framework 2.0 SP1 or 3.0 SP1. If your system has one of the 2.0 SP1 or 3.0 SP1 registry values present but does not have the corresponding MSI installed, then the same workarounds described above can help resolve this .NET Framework 3.5 installation issue as well.

Final note

There are many possible causes for .NET Framework 2.0 SP1, .NET Framework 3.0 SP1 and .NET Framework 3.5 setup failures. The scenario in this blog post only describes one possibility. If you are encountering a .NET Framework installation failure but have different symptoms or different information in your log files, you are likely running into a different problem. In those cases, I suggest consulting the .NET Framework setup troubleshooting guide for links to other possible installation issues and workarounds, links to log file locations, links to readme files, etc.

<update date="12/2/2009"> Fixed broken links to images used in this blog post. </update>

The .NET Framework 3.5 installs a copy of its setup files to the folder %windir%\Microsoft.NET\Framework\v3.5\Microsoft .NET Framework 3.5, and this location is the one that is launched when you go to Add/Remove Programs and choose to repair or uninstall the .NET Framework 3.5. The setup.exe in this location can also be called directly in order to automate the repair or uninstall of the .NET Framework 3.5.

The following command lines can be used to repair and uninstall the .NET Framework 3.5. The silent option will perform the repair/uninstall with no UI displayed to the user. The unattended option will perform the repair/uninstall with only a progress dialog, but with no user interaction required.

Note: There are a few things to keep in mind about the above instructions:

When calling .NET Framework 3.5 setup in silent or unattended mode, you should check the return code from the setup.exe process in order to determine success or failure. Return code 0 means that the setup was successful, return code 3010 means that the setup was successful but a reboot is required to complete the setup and any other return code means that there was an error.

Log files will be created for the .NET Framework 3.5 repair and uninstall just like for the initial install. You can find a list of .NET Framework 3.5 log files in this blog post.

The .NET Framework 3.5 repair process will chain the repair processes for the .NET Framework 2.0 SP1 and the .NET Framework 3.0 SP1, so there is no need to use separate steps to repair those products if you are going to repair the .NET Framework 3.5.

The .NET Framework 3.5 uninstall process will only uninstall the .NET Framework 3.5 MSI. It will not uninstall the .NET Framework 2.0 SP1 or the .NET Framework 3.0 SP1 products because there may be other applications on the system that rely on those versions of the .NET Framework. If you want to uninstall the .NET Framework 2.0 SP1 and 3.0 SP1, you must uninstall in the following order: .NET Framework 3.5, then .NET Framework 3.0 SP1 then .NET Framework 2.0 SP1.

When I am attempting to investigate a setup-related failure, I typically end up looking at verbose log files. These log files can contain information about a wide variety of failures, and the failures will typically include some detailed error information (such as the information reported by the GetLastError and FormatMessage APIs or something equivalent to them). In the case of verbose Windows Installer log files, I find the error information in most cases by searching for the text "return value 3" as described in this blog post.

Once I find the error information, I can often recognize the error codes from my past experience. However, there are also a lot of cases where I run into error codes that I do not recognize from past experience. When that happens, I use a tool that helps me translate error codes (normally HRESULT values from function calls) into more readable information. Doing this can help me better understand what the error means, which in turn can help give ideas for what might be causing the error and what types of fixes might help eliminate the error.

Recently, I discovered that the tool that I've been using to do error code translation is available on the Microsoft Download Center so that anyone can get a copy and use it themselves. You can find the tool, called Err.exe, at http://www.microsoft.com/downloads/details.aspx?familyid=be596899-7bb8-4208-b7fc-09e02a13696c. This site describes the tool as an Exchange Server Error Code Look-up, but this tool actually aggregates information from 172 sources (header files, etc) from Windows and various other products around Microsoft and is not only useful for Exchange Server issues.

For example, it includes information from corerror.h (a header file that ships with the .NET Framework SDK and Windows SDK) so it can report error information for some types of .NET Framework errors. Here are a couple of specific examples of the output produced by err.exe:

In some cases, as shown above for error code 0x80070005, the same error code can map to different meanings in different header files. In those cases, it is sometimes necessary to make an educated guess about which one is the actual error code being generated by a setup error. For example, in most cases, if an error code from winerror.h is listed in the output from err.exe, that one is the actual error code.

It is important to note that Err.exe is not intended to be a diagnostic tool on its own. In other words, it will not be able to tell you how to fix a problem just based on what the error code is. However, in my experience, Err.exe is very useful as a step along the path of attempting to solve a problem because it provides additional information about what an error code means. Once you have a better idea about what an error code means, you can often use this additional information to perform some additional Web searches to learn about possible causes of and workarounds for specific types of errors.

A new cumulative update package for Windows Vista Media Center has been released this week. This update is called the June 2008 Cumulative Update for Media Center for Windows Vista and is also known as KB950126. It is available for download in x86 and x64 versions. It can be installed on systems running the original version of Windows Vista Home Premium or Ultimate Editions and the SP1 version of Windows Vista Home Premium or Ultimate Editions.

Last week, I started looking at the beta version of the .NET Framework 3.5 client profile in more detail in order to better understand how it works behind the scenes, and I wrote a brief blog post based on my initial experiences. While looking at it, I ran into a few installation issues that I didn't see documented, so I sent a few questions off to the folks I know who are working on the client profile project (including Troy Martez). It turns out that the issues I saw are all known by the team and are being looked at post-beta, but haven't been posted publicly yet. After talking with Troy, I decided to post the issues and workarounds (if applicable) to help raise awareness in the meantime.

After installing the .NET Framework 3.5 client profile beta, attempting to install the full version of the .NET Framework 2.0, 2.0 SP1, 3.0, 3.0 SP1 or 3.5 will cause a crash dialog from a process named DotNetInstallBlock.exe. If you need to install any other version of the .NET Framework on a system with the .NET Framework 3.5 client profile beta installed, you will first need to remove the .NET Framework 3.5 client profile beta from your system (details below in Issue 4).

Issue 2: Crash dialog when attempting to install applications that depend on the .NET Framework 2.0, 3.0 or 3.5

If I try to run an application that installs the .NET Framework 2.0, 3.0 or 3.5 as a chained prerequisite (such as Visual Studio 2005), the application does not detect that the .NET Framework 2.0, 3.0 or 3.5 are already installed because the client profile does not create the same set of detection registry keys. As a result, it it tries to invoke .NET Framework setup, and that in turn ends up causing DotNetInstallBlock.exe to be invoked. Just like in Issue 1 above, DotNetInstallBlock.exe crashes and the application installation process fails. If you need to install any applications that include the .NET Framework as a part of their setup on a system with the .NET Framework 3.5 client profile beta installed, you will first need to remove the .NET Framework 3.5 client profile beta from your system (details below in Issue 4).

After installing the .NET Framework 3.5 client profile beta, you cannot install the .NET Framework 1.0 or 1.1 even though those versions of the .NET Framework should allow you to install side-by-side with the client profile. Attempting to do so will cause a crash dialog from a process named DotNetInstallBlock.exe. If you need to install the .NET Framework 1.0 or 1.1 on a system with the .NET Framework 3.5 client profile beta installed, you will need to remove the .NET Framework 3.5 client profile beta from your system (details below in Issue 4), then install the .NET Framework 1.0 or 1.1, then re-install the .NET Framework 3.5 client profile beta.

Issue 4: Uninstall is a multi-step process that must occur in a specific order

The .NET Framework 3.5 client profile beta adds 3 separate entries to the Add/Remove Programs control panel. When uninstalling the client profile beta, you must make sure to uninstall in a particular order in order for the uninstall process to successfully remove everything that it needs to. Specifically, you should remove the packages in the following order:

Microsoft .NET Framework 3.5 Client Service Pack 1 Beta 1

Microsoft .NET Framework 3.0 Client Service Pack 2 Beta 1

Microsoft .NET Framework 2.0 Client Service Pack 2 Beta 1

Issue 5: Prerequisite components are downloaded and installed even if they are already present on the system

The .NET Framework 3.5 client profile beta includes 2 prerequisite components that are also installed by the .NET Framework 3.0 and 3.5 - RGBRast and Windows Imaging Components (WIC). The beta installer always downloads and installs these prerequisites, even if they are already present on the system. This does not harm anything, but results in unnecessary downloads in some cases.

I am attempting to automate the installation of the Visual Studio 2008 SDK, but have not been able to figure out how to do so. Running vssdk_sfx.exe /? just displays the normal setup UI and not a usage dialog, and I haven't been able to find any deployment documentation for this product. How can I perform a silent install of the VS 2008 SDK?

Answer:

The Visual Studio 2008 SDK can be installed in silent mode by using the following steps:

Extract the contents of the VS SDK setup by running the following: vssdk_sfx.exe /x:%temp%\vssdk2008_setup /q

Run the VS SDK MSI in silent mode from within the extracted folder by running the following: msiexec /i %temp%\vssdk2008_setup\vssdk.msi /qn /l*v %temp%\vssdk2008setup.txt

(optionally) Delete the copy of VS SDK setup that you extracted in step 2 by running the following: rd /s /q %temp%\vssdk2008_setup

A couple of notes to keep in mind when doing this:

When running VS SDK setup in full UI mode, there is a check-box that allows you to choose not to install the documentation. The command line in step 3 above will install the default set of features for the VS 2008 SDK, which will include the documentation. If you need to install a non-default set of features, you will need to figure out the feature names from the MSI and then add the ADDLOCAL property to the end of the command line in step 3. The easiest way I've seen to do this is to enable Windows Installer verbose logging using these steps, then install in full UI mode with the documentation item unchecked. After the installation completes, you can look at the verbose log file created by the VS SDK installer in the %temp% directory and copy the exact value passed in for the ADDLOCAL property from that log file.

The command line in step 3 above will perform a fully silent install of the VS 2008 SDK. If you want to perform an unattended install instead (meaning, there will be a small progress dialog during installation but no user interaction will be required), then you can change the /qn switch to /qb in the command line in step 3. Note that if you do that, the progress dialog will be blank during installation because the VS SDK MSI does not include the necessary strings in the ActionText and Error tables. In my experiments, I found that an unattended installation appears to be hung for a long time towards the end of installation while it is merging the SDK help documentation and completing the installation because the progress bar does not move and the progress dialog has no text. I was able to see the installer continue to make progress by looking at the processes in Task Manager and by looking at the verbose log file at %temp%\vssdk2008setup.txt.

<update date="6/20/2008"> The VS SDK installer does not enable Windows Installer verbose logging by default. Added a link to information about how to enable verbose logging if needed. </update>

When authoring deferred custom actions (which are custom actions that change the system state) in an MSI, it is necessary to also provide an equivalent set of rollback custom actions to undo the system state change in case the MSI fails and rolls back. The rollback behavior typically needs to behave differently depending on if the MSI is currently being installed, repaired or uninstalled. This means that the following scenarios need to be accounted for when coding and testing a set of deferred custom actions to make sure that they are working as expected during both success and failure cases:

Successful install

Failed install

Successful repair

Failed repair

Successful uninstall

Failed uninstall

The scenario in this blog post provides an example of what can happen when rollback custom actions do not behave the way they should.

The failure cases are often difficult to simulate by unit testing the custom action code directly because deferred custom action code typically depends on state information provided to it by Windows Installer during an active installation session. As a result, this type of testing usually requires fault injection in order to cause the rollback custom actions to be executed at the proper times during real installation scenarios.

Bob Arnson recently posted an item about a useful feature that he recently added to WiX v3.0 to help test rollback custom actions in an MSI. This feature is a simple deferred custom action named WixFailWhenDeferred that will always fail when it is executed during the installation, repair or uninstallation of an MSI. Adding the WixFailWhenDeferred custom action to your MSI allows you to easily inject a failure into your MSI in order to test your rollback custom actions.

There are 3 steps you need to take to use this technique to test the rollback custom actions in your MSI:

1. Add a reference to the WixFailWhenDeferred custom action

To add a reference to this custom action, include the following in your WiX v3.0 setup authoring:

<CustomActionRef Id="WixFailWhenDeferred"/>

This will cause WiX to add the WixFailWhenDeferred custom action to your MSI, schedule it immediately before the InstallFinalize action and condition it to only run if the property WIXFAILWHENDEFERRED=1.

2. Add a reference to the WixUtilExtension to your WiX project

When running WiX tools directly, this means adding a parameter to the light.exe command line like the following:

light.exe myproject.wixobj -ext WixUtilExtension.dll

When using Votive and Visual Studio for your WiX project, you can add a reference to WixUtilExtension by using the following steps:

Right-click on the References node of the WiX project in the Solution Explorer and choose Add Reference...

In the Add Reference dialog, click on the Browse tab.

Locate WixUtilExtension.dll and click the Add button, then click OK to dismiss the dialog.

3. Set the WIXFAILWHENDEFERRED property to 1 when installing the MSI to trigger rollback

The WixFailWhenDeferred custom action is conditioned to run only when the Windows Installer public property WIXFAILWHENDEFERRED=1. After building an MSI that includes a reference to the WixFailWhenDeferred custom action, the following set of command lines can be used to simulate a set of standard install and rollback testing scenarios:

A little while ago, Bob Arnson posted a description of the WixGamingExtension, which was added to WiX v3.0 to allow setup developers to integrate their game with the Windows Vista Game Explorer. When he created the WixGamingExtension, he also created another smaller extension that he didn't publicize outside of the WiX help documentation (wix.chm).

The other extension is called the WixDirectXExtension, and I want to describe it in more detail here because it contains a couple of system configuration detection custom actions that are typically useful for game developers who are creating MSI-based installers for their games.

Description of the WixDirectXExtension

The WixDirectXExtension has been available in WiX v3.0 since the 3.0.4014.0 build. The WixDirectXExtension contains a custom action named WixQueryDirectXCaps. This custom action queries the DirectX capabilities of the video card on a user's system and then set the following MSI properties:

WIX_DIRECTX_PIXELSHADERVERSION - Pixel shader version capability, expressed as major*100 + minor. For example, a shader model 3.0-compliant system would have a WIX_DIRECTX_PIXELSHADERVERSION value of 300.

WIX_DIRECTX_VERTEXSHADERVERSION - Vertex shader version capability, expressed as major*100 + minor. For example, a shader model 3.0-compliant system would have a WIX_DIRECTX_VERTEXSHADERVERSION value of 300.

How to use WixDirectXExtension in your setup authoring

To use the WixDirectXExtension properties in your WiX v3.0-based setup, you can use the following steps:

Add PropertyRef elements for items listed above that you want to use in your MSI.

Add authoring to your MSI to use the resulting property somehow (such as to warn the user if the pixel shader version is less than what is required by the product being installed).

Add the -ext <path to WixDirectXExtension.dll> command line parameter when calling light.exe to include the WixDirectXExtension in the MSI linking process. Or, using an MSBuild-based .wixproj project, add <path to WixDirectXExtension.dll> to the WixExtension item group. When using Votive in Visual Studio 2005 or Visual Studio 2008, this can be done by right-clicking on the References node in a WiX project, choosing Add Reference... then browsing for WixDirectXExtension.dll and adding a reference.

Note that the WixDirectXExtension properties are set to the value NotSet by default. The WixDirectXExtension custom action is configured to not fail if it encounters any errors when trying to determine DirectX capabilities. In this type of scenario, the properties will be set to their NotSet default values. In your setup authoring, you can compare the property values to the NotSet value or to a specific value to determine whether WixDirectXExtension was able to query DirectX capabilities and if so, what they are.

What WixDirectXExtension does behind the scenes

If you're interested, the WixQueryDirectXCaps custom action does the following behind the scenes:

The total download size for the Windows Installer 4.5 SDK is 6.8 megabytes. This is the first time I recall a small standalone Windows Installer SDK being released like this. In the past, getting the Windows Installer SDK required installing a core subset of the Windows SDK or Platform SDK. This meant you had to download and install a rather large SDK to get copies of Windows Installer tools like Orca.

The Windows Installer 4.5 SDK includes a copy of the Windows Installer help documentation in CHM format. It is located at %ProgramFiles%\Windows Installer 4.5 SDK\Doc\msi45.chm if you install the SDK to the default location. This CHM file has not shipped with the Windows Installer SDK in a while, and it is a handy reference for Windows Installer-specific information, especially on systems that do not have Internet access.

In addition to the above, the Windows Installer 4.5 SDK includes the following components (which have also been shipped in previous versions of the Windows Installer SDK)

Updated versions of a set of useful tools, including the installer for Orca (Orca.msi) and several others. The tools are located at %ProgramFiles%\Windows Installer 4.5 SDK\Tools if you install the SDK to the default location.

Headers, libraries, patch building samples and sample code that can be useful to Windows Installer developers.

A little while ago, I posted an item about the XNA Game Studio 2.0 Japanese documentation package that was released by the XNA community gaming platform team. This package allows you to install a local collection of Japanese help topics for the XNA Game Studio 2.0 product. This documentation is stored on the local file system and can be accessed in the Visual Studio help viewer even if the computer does not have an active Internet connection.

Recently, the XNA Game Studio 2.0 Japanese help documentation was also published to the online MSDN library at http://msdn.microsoft.com/ja-jp/library/bb200104.aspx. This enables users to search online for Japanese help topics for XNA Game Studio 2.0. In addition, you can configure Visual Studio 2005 and Visual C# 2005 Express Edition to automatically load the online Japanese help documentation first if it is able to access the Internet. To change the Visual Studio online help language preferences, you can do the following:

If you are running Visual C# 2005 Express Edition, click the check box in the bottom left corner of the Options dialog to show all settings

Under the Environment item, click on the Help item

Change the Online topic language to Japanese if it is not already set that way

Click on the Online item

In the radio button group labeled When loading Help content, choose one of the options that will allow Visual Studio to attempt to load online content

These steps will allow you to view Japanese help documentation for XNA Game Studio 2.0 even if you do not download and install the Japanese documentation package, but it does require your computer to have Internet access at the time you try to view help topics. You can also click the check box on the Help item in the Visual Studio options page to cause it to display the English versions of the help topics as well if you choose to.