Aaron Stebner's WebLog

Thoughts about setup and deployment issues, WiX, XNA, the .NET Framework and Visual Studio

  • Aaron Stebner's WebLog

    How to fix .NET Framework 1.1 setup failure on Windows Vista build 5456

    • 19 Comments

    Important note: The issue described in this blog post only affects pre-RC1 builds of Windows Vista.  If you are running Windows Vista RTM and have problems installing the .NET Framework, do not try this workaround because it does not apply to the RTM build and will not help.  Please see http://blogs.msdn.com/astebner/articles/454956.aspx instead of this blog post if you have problems installing the .NET Framework 1.1 on Windows Vista RTM.....

    The .NET Framework setup team recently discovered a compatibility bug that will prevent the .NET Framework 1.1 from installing on the most recent build of Windows Vista that was released to the Windows Vista beta program members (build 5456). 

    The underlying problem is that one of the type libraries registered by .NET Framework 1.1 setup is attempting to write to a registry sub-key that is incorrectly marked read-only in this build of Windows Vista.  In order to workaround this issue, you will need to change owners and modify permissions on a registry sub-key on your system.

    You can perform the following steps before installing the .NET Framework 1.1 to workaround this issue on Windows Vista build 5456:

    1. Click on the Start menu, choose All Programs, then Accessories
    2. Right-click on Command Prompt and choose Run as administrator
    3. From the command prompt, type regedit
    4. Navigate to HKEY_LOCAL_MACHINE and then Software\Classes\Interface\{65074F7F-63C0-304E-AF0A-D51741CB4A8D}\TypeLib
    5. Right-click on the TypeLib sub-key and choose Permissions
    6. Click the Advanced button
    7. Click on the Owner tab
    8. Select the Administrators group in the Change owner to: list and click Apply to change the owner of this sub-key
    9. Click on the Permissions tab, highlight SYSTEM and click the Edit button
    10. Check the Full Control check box and click OK to change the permissions on this sub-key for the SYSTEM account
    11. Close regedit

    After performing the above steps, you should be able to re-run .NET Framework 1.1 setup and install successfully.

    <update date="4/4/2007"> Added note at the top of this blog post to try to let users know that this workaround will not help in the final RTM release of Windows Vista.  </update>

     

  • Aaron Stebner's WebLog

    How to modify the default install path in an MSI-based setup based on a registry value

    • 6 Comments

    I got a question from a customer this week asking how they could modify the default installation path in their MSI-based setup package based on a value they wanted to retrieve from the registry.  Typically this kind of modification is desired if your setup shares files/components with another MSI, and that other MSI can be installed to non-default locations by another setup package.  The steps to accomplish this are roughly the following.  Please note that I am basing this algorithm on how we accomplish this inside of Visual Studio setup (I also described what happens behind the scenes in VS setup in more detail here).  There may be alternative ways to accomplish the same result.

    1. Create a new entry in the AppSearch table that contains the Signature_ you want to search for and a specific Property name that will store the data you retrieve
    2. Create an entry in the RegLocator table that has a Signature_ column name that matches the Signature_ column name you added to the AppSearch table in step 1 above and that contains the key/value you want to retrieve and use if it exists on the user's system
    3. Create an entry in the CustomAction table that has a Target value that matches the Property column name you added to the AppSearch table in step 1 above (and is in square brackets since this is an MSI property and it needs to be referenced in square brackets to resolve correctly here), and has a Source name that matches the name of the directory in the Directory table that you want to change the default installation path for
    4. Add an entry to the InstallExecuteSequence table that has an Action column name that matches the name of the custom action added in step 3 above and has a Condition column name that matches the Property column name you added to the AppSearch table in step 1 above.  This will ensure that you will only try to change the installation directory if the registry value you are searching for exists on the user's system, and your MSI will use the default installation directory if the registry value is missing.

     

  • Aaron Stebner's WebLog

    Don't use vbscript/jscript to write your custom actions!

    • 16 Comments

    Rob Mensching wrote a blog entry a while back that explains some reasons why you should not use script-based custom actions in your setup.  I encourage you all to read it if you haven't yet, and I also strongly encourage you to heed his recommendations if at all possible.

    I can personally relate to one of his explanations as well.  Reason #3 on his list talks about anti-virus programs.  When we shipped Visual Studio .NET 2002 we started getting reports of seemingly random failures during setup from our product support team.  After some detailed analysis we found that many of these failures were being caused by overly aggressive anti-virus programs that were blocking scripts from running even as part of custom actions during VS setup.  We scrubbed our custom actions before shipping Visual Studio .NET 2003 to re-write or eliminate the script-based custom actions to avoid these failures, and we were able to eliminate a fairly high support call generator.

     

  • Aaron Stebner's WebLog

    Disabling services with MSConfig to work around setup failures

    • 12 Comments

    I was talking recently with a colleague who works on the .NET Framework setup and Windows Installer technical support team here at Microsoft.  He told me about a set of steps that his team typically has customers try when they call in to report failed installations.  I wanted to post these steps here in case they are helpful to anyone else struggling to get an application installed.

    This set of steps allows you to easily find all services that are installed on your system and temporarily disable them so they cannot interfere with installation processes.  It also allows you to identify and temporarily disable programs that are scheduled to start every time the system reboots.  The System Configuration tool (also known as MSConfig) allows you to manage these and other settings.

    I recommend trying the following steps in cases where a product fails to install on your system and you've already tried other workarounds posted on my blog and elsewhere to attempt to resolve the issue:

    1. Click on the Start menu, choose Run, type msconfig and click OK
    2. In the System Configuration tool, click on the Services tab
    3. Check the box labeled Hide all Microsoft services
    4. Click the Disable All button to disable all non-Microsoft services
    5. In the System Configuration tool, click on the General tab
    6. Click the Selective startup radio button
    7. Uncheck the box labeled Load startup items
    8. Click OK to accept all changes in the System Configuration tool
    9. Reboot for the changes to take effect
    10. Attempt to install the application that previously failed
    11. Re-run the System Configuration tool and re-enable the services that you disabled in step 4 above

    In many cases, the above steps will allow a previously failing setup package to install successfully.  Hopefully they will be useful to you as well if you find yourself in this situation.

  • Aaron Stebner's WebLog

    Example of how to use Visual Studio IDE language switching

    • 16 Comments

    Recently, I wrote a couple of blog post (here and here) about how to enable multi-lingual development scenarios by taking advantage of the Visual Studio IDE UI language switching feature.  I would like to add to those previous posts by showing an example of using this feature, including some screenshots.

    For this example, I will use the English and French versions of the Visual C# 2005 Express Edition.  However, it works equally well for any version and UI language of Visual Studio.

    I configured my system as follows:

    1. I installed the English version of the Visual C# 2005 Express Edition
    2. I launched the VC# IDE to verify that everything worked as expected
    3. I installed the French version of the Visual C# 2005 Express Edition
    4. I launched the VC# IDE again to verify that everything still worked.  The UI remained in English even though I had installed the French version because this setting was set to use English UI when I launched the IDE in step 2 above

    Now that I have both the French and English versions of VC# Express installed, I can easily switch IDE UI languages.  When I launch the IDE with English UI, it appears as follows:

    Visual C# 2005 Express Edition IDE with English UI

    Once I launch the IDE with English UI, I can do the following to change the UI language to French:

    1. Click on the Tools menu and choose Options...
    2. Check the Show all settings check box at the bottom left of the screen (which is unchecked by default in the VS 2005 Express Editions)
    3. Click the International Settings option under the Environment item in the tree control on the left side of the Options dialog
    4. Select francais in the Language drop down
    5. Click OK to confirm the language change and then press OK on the notification dialog that appears to indicate that the IDE must be restarted for the change to take effect
    6. Close and reopen the IDE

    The English Options dialog looks like the following:

    Visual C# 2005 Express Edition English international settings dialog

    After following the above steps and then reopening the IDE, VC# will appear as follows:

    Visual C# 2005 Express Edition IDE with French UI

    I am able to change the language back to English by using the same set of steps as listed above, except I need to refer to the French translation for each of the IDE UI elements.  The French Options dialog looks like the following: 

    Visual C# 2005 Express Edition French international settings dialog

    In addition to using the steps listed above, I can change the IDE UI language by using the following command lines:

    • To launch the IDE with English UI: %ProgramFiles%\Microsoft Visual Studio 8\Common7\IDE\vcsexpress.exe /LCID 1033
    • To launch the IDE with French UI: %ProgramFiles%\Microsoft Visual Studio 8\Common7\IDE\vcsexpress.exe /LCID 1036

    It is important to note that when using the /LCID command line switch, the default UI language will be updated in the registry when Visual Studio launches.  That means that if you had previously configured VS to launch in English and you then pass in /LCID 1036, you will set the default language to French.  That means that when you close the IDE and reopen it using the Start menu shortcut it will continue to appear with French UI until you change it in the International Settings section of the Options dialog or launch the IDE with /LCID 1033.

    One other interesting note that I want to emphasize here - IDE language switching will be available even if you don't install the exact same edition of Visual Studio for each language.  For example, you can install the English Visual Studio Team Suite and the French Visual Studio Professional.  However, the only UI that will correctly switch languages will be components that are common to the two editions that you install on your system.  So you might see a mix of two different UI languages depending on what editions you have installed on your system and what features you use within the IDE.  In addition, there are limitations in the UI language fallback mechanism for some IDE features, so you may see some features missing from the IDE even though the feature is installed for one of the two UI languages.

    <update date="2/10/2011"> Fixed broken links to images used in this post. </update>

  • Aaron Stebner's WebLog

    Scenarios where .NET Framework 3.5 setup tries to connect to the Internet and how to avoid them

    • 30 Comments

    The setup program for the .NET Framework 3.5 and the Visual Studio 2008 Express Editions contains logic that will cause it to attempt to connect to the Internet to download files in some scenarios.  I've heard from several folks who have asked me why this happens and how to prevent it in case they need to install in a fully offline scenario where the system has no Internet connectivity.  This post will describe the cases I know of where .NET Framework 3.5 and VS 2008 Express Edition setup will attempt to download files from the Internet and how they can be avoided if necessary.

    Case 1 - Missing setup packages

    .NET Framework 3.5 and Visual Studio 2008 Express Edition setup both have logic to search in relative paths next to setup.exe for packages that need to be installed during the setup process.  If any of the packages are not found in those relative paths, setup will use URL values constructed from information in the setup data file named baseline.dat to attempt to download the packages from the Internet instead.  If setup cannot connect to the Internet or the download fails for any reason, then setup will fail and report an error.

    In order to avoid requiring Internet access in this scenario, you need to make sure to construct an install point for the .NET Framework 3.5 or the Visual Studio 2008 Express Editions that include all packages that could need to be installed in your environments.  You can find more information about how to do this in the following blog posts:

    If you are interested, you can find more information about how this automatic download functionality works in .NET Framework 3.5 setup here and here.  The VS 2008 Express Edition setup packages use the same setup.exe code as the .NET Framework 3.5 setup, so the behind-the-scenes logic is similar for those packages.

    Case 2 - Installing the .NET Framework 3.5 on a non-English OS

    The .NET Framework 3.5 setup contains logic to check the language of the OS that it is being installed on and attempt to install a language pack that matches the OS language if one is available.  However, the "full install" setup package for the .NET Framework 3.5 does not include any language packs, so setup will attempt to connect to the Internet when this package is run on many non-English language OS's.

    In order to avoid requiring Internet access in this scenario, you can use one of the following techniques:

    • Download the .NET Framework 3.5 language packs that could be needed in your environments and copy them into your installable .NET Framework 3.5 layout.  You can find download locations for the .NET Framework 3.5 language packs in this blog post and instructions regarding where to copy them in your .NET Framework 3.5 installable layout in item 2 in this blog post.
    • Run .NET Framework 3.5 setup with the /lang switch and pass in the value ENU to prevent it from attempting to install any language packs.  This is described in item 1 in this blog post.

    Note - .NET Framework 3.5 setup is configured to report warnings as opposed to failures if it is unable to download or install language packs.  That means that the above steps are not required in order to allow setup to succeed in offline scenarios, but these steps are required if you want to avoid any attempts to connect to the Internet during .NET Framework 3.5 setup on non-English operating systems.

    Case 3 - Checking for a new version of setup

    The setup programs for the .NET Framework 3.5 and the Visual Studio 2008 Express Editions contain logic to cause them to connect to the Internet to search for an updated version of the setup program.  This will only happen if setup is run with the /web command line switch.  The .NET Framework 3.5 setup program (dotnetfx35setup.exe) and the web download bootstrapper packages for the Visual Studio 2008 Express Editions (vbsetup.exe, vcsetup.exe, vcssetup.exe and vnssetup.exe) are self-extracting packages that are configured to unpack and then run the setup.exe contained within the package with the /web switch.

    In order to avoid having .NET Framework 3.5 setup connect to the Internet to search for an updated version of itself, you must do the following:

    1. Create an installable layout using the steps in this blog post
    2. Go to the folder that you extracted the .NET Framework 3.5 setup files to, find the file named dotnetfx35setup.exe and run dotnetfx35setup.exe /x to unpack it
    3. When prompted, choose to unpack it to the same folder it is currently located in
    4. Instead of using the file dotnetfx35setup.exe to start installing the .NET Framework 3.5, use the file setup.exe in the unpacked location.  This will cause setup to run without the /web switch and skip the step of connecting to the Internet to search for a new copy of setup.  The setup.exe file takes the same command line parameters as dotnetfx35setup.exe (such as the /q and /norestart switches for silent installation).

    For the Visual Studio 2008 Express Editions, only the web download bootstrapper packages available from this download page are configured to use the /web switch.  If you use the instructions for creating an installable layout in this blog post, you will end up unpacking the package that has the /web switch built into it, and running from the layout you create will not end up searching for a new instance of itself during setup.

    Note - .NET Framework 3.5 and VS 2008 Express Edition setups are configured to not fail if they are unable to connect to the Internet to check for a new instance of setup.  That means that the above steps are not required in order to allow setup to succeed in offline scenarios, but these steps are required if you want to avoid any attempts to connect to the Internet during .NET Framework 3.5 setup.

  • Aaron Stebner's WebLog

    Updated version of the .NET Framework cleanup tool that can remove the .NET Framework 3.5

    • 15 Comments

    I've posted an updated version of the .NET Framework cleanup tool that now contains an option to remove the .NET Framework 3.5 (in addition to 1.0, 1.1, 2.0 and 3.0).  I also added some additional information to be removed when uninstalling the .NET Framework 1.1 (thanks to this comment on one of my other blog posts).

    You can use the following links to find more information about the .NET Framework cleanup tool and download it if you need it on your system:

    Note - at the time that I am writing this blog post, the .NET Framework 3.5 is still only a beta, so currently the cleanup tool is only able to remove the beta 1 and beta 2 versions of the .NET Framework 3.5.  I will update the tool in the future when future builds of the .NET Framework 3.5 are released publicly.

    <update date="5/19/2008"> Added an alternate download location for the cleanup tool in case the first site is down. </update>

     

  • Aaron Stebner's WebLog

    New simplified silent install switches are available for Visual Studio 2008 setup

    • 24 Comments

    Visual Studio 2002, 2003 and 2005 setups include a silent deployment mode that requires multiple steps (creating an INI file on the matching OS version and language, then running VS setup and passing it the INI file to perform the installation).  Those of you who have automated the installation of these versions of Visual Studio can attest to the difficulties that this multi-step, OS version-specific process has introduced.

    In order to make the most commonly needed automated installation scenarios easier to achieve, the following command line switches have been added to Visual Studio 2008 setup:

    • setup.exe /q - this will perform a silent default installation of VS 2008. This is the equivalent of running VS 2008 setup using setup UI and selecting the Default install type radio button.
    • setup.exe /q /full - this will perform a silent full installation of VS 2008. This is the equivalent of running VS 2008 setup using setup UI and selecting the Full install type radio button.

    Note - if you need to pass in a product key when running setup using these new silent switches, you will need to use the syntax described in this blog post.

    There are some important notes to keep in mind for these new silent install options:

    • When using these command line switches, you must make sure that you pass them to the setup.exe in the Setup subdirectory, and not to the setup.exe at the root of the VS 2008 installation disc.  Only the setup.exe in the Setup subdirectory understands these command line parameters.
    • If you run setup.exe /q on a system that already has that edition of VS 2008 installed, it will invoke a silent repair instead of a silent installation.
    • If you need to perform a silent non-default installation of VS 2008 (as opposed to a default or a full installation), then your best bet will be to use the INI creation mode that has existed in previous versions of VS 2008.
    • It is also possible to gather a list of feature names that you want to install by running VS 2008 setup once in UI mode, selecting the features you want to install in the setup UI feature tree, then looking at the verbose MSI log file that is created during installation to figure out the exact list of feature names to pass in during silent installation.  However, that option is more complicated and error-prone than INI creation mode, so I don't recommend using this method unless absolutely necessary.
    • If you want to be able to control reboots, you can also pass in the /norestart switch.  This will prevent setup from forcing a reboot during installation if one of the components it is installing requests one.  It does not, however, postpone the reboot until the end of setup.  In some cases, the setup team determined that it is not safe to defer reboot requests for a component, and have set a flag in a setup data file to indicate that (specifically, the flag RebootLaterOk=0 in baseline.dat).  If one of these components returns 3010, and you pass in the /norestart switch, then setup will exit but will not reboot.  It is up to the process running the silent install to reboot the system and re-start setup after the reboot in order to allow setup to continue.
    • To avoid reboots, you can configure your systems with any prerequisite packages that tend to cause reboot requests prior to deploying VS 2008.  Doing this will cause VS 2008 setup to skip installing those prerequisites because setup will detect that they are already present on the system.

    <update date="9/20/2007"> Added more details about how the /norestart switch works </update>

    <update date="12/17/2008"> Added a link to a separate blog post I wrote about how to pass a product key into setup when using the /q switch. </update>

     

  • Aaron Stebner's WebLog

    How to resolve invalid license data errors after upgrading to the final release of Visual Studio 2005

    • 22 Comments

    I have heard from a couple of customers who have uninstalled beta versions of Visual Studio 2005 and then installed the final release.  After installation finished, they saw a small error dialog that looks like the following when trying to launch the Visual Studio 2005 IDE:

    Visual Studio 2005 invalid license data error

    Pressing OK on this dialog dismisses the IDE and VS 2005 is not usable.

    There are a couple of cases where registry data can be orphaned on the machine that causes this type of error.  Unfortunately, because this data is written by a custom action and there are some "interesting" conditions on that cusotm action in the VS MSI, running a repair of VS 2005 will not correctly fix the registry values that control this functionality.

    The following steps can be used to resolve this Invalid license data error message:

    1. Uninstall the Visual Studio 2005 product that you have installed.  You only have to uninstall the main Visual Studio product entry in Add or Remove Programs, and you can leave the other pieces installed by Visual Studio setup (such as the .NET Framework 2.0, MSDN, SQL Express, etc) alone.  The product name in Add or Remove Programs that you want to uninstall is dependent on the VS 2005 edition you have installed.  For example, for the English Professional edition, the product name will be "Microsoft Visual Studio 2005 Professional - ENU"
    2. Click on Start, choose Run and type cmd
    3. Copy and paste each of the following commands into the cmd prompt to clean up orphaned Visual Studio licensing data in your registry: 
      reg delete HKCR\Licenses\17A13F5F-2dE4-4691-B332-83CA4CC38935 /f
      reg delete HKCR\Licenses\2F1682F3-6A3C-4545-AF41-6836A22276CF /f
      reg delete HKCR\Licenses\2FE88699-A1AF-410D-8049-1CB6BA8F8FF2 /f
      reg delete HKCR\Licenses\5BCBC240-27DF-49C1-8C1C-27B8463009A9 /f
      reg delete HKCR\Licenses\895E2152-C3F9-4C49-968B-15B08ADA0F37 /f
      reg delete HKCR\Licenses\95C63E85-8244-4D86-8327-579B85EC154C /f
      reg delete HKCR\Licenses\BA32367F-28F8-4AEA-848D-95AE438B3B9C /f
    4. If you are installing on a 64-bit OS, copy and paste each of the following commands into the cmd prompt to clean up orphaned Visual Studio licensing data in your registry:
      reg delete HKCR\Wow6432Node\Licenses\17A13F5F-2dE4-4691-B332-83CA4CC38935 /f
      reg delete HKCR\Wow6432Node\Licenses\2F1682F3-6A3C-4545-AF41-6836A22276CF /f
      reg delete HKCR\Wow6432Node\Licenses\2FE88699-A1AF-410D-8049-1CB6BA8F8FF2 /f
      reg delete HKCR\Wow6432Node\Licenses\5BCBC240-27DF-49C1-8C1C-27B8463009A9 /f
      reg delete HKCR\Wow6432Node\Licenses\895E2152-C3F9-4C49-968B-15B08ADA0F37 /f
      reg delete HKCR\Wow6432Node\Licenses\95C63E85-8244-4D86-8327-579B85EC154C /f
      reg delete HKCR\Wow6432Node\Licenses\BA32367F-28F8-4AEA-848D-95AE438B3B9C /f
    5. Re-install the Visual Studio 2005 product that you uninstalled in step 1 above

    After doing this, the license data should be recreated and correct and allow you to launch the VS 2005 IDE.

    <update date="10/25/2006"> Added some more licensing registry values and a new section for 64-bit registry values that need to be removed </update>

    <update date="8/27/2009"> Fixed broken link to image. </update>

     

  • Aaron Stebner's WebLog

    Error installing .NET Framework on Windows XP SP2 caused by language settings

    • 24 Comments

    Note - the issue described in this blog post was originally presented as an issue on Windows XP SP2.  However, it can also affect .NET Framework 1.0 and 1.1 installation on any OS released after the .NET Framework 1.0 and 1.1 shipped - specifically, I have seen reports of this issue on Windows Vista.  The steps listed here are applicable to this type of install failure on other newer OS's like Windows Vista and not just Windows XP SP2.  

    I was contacted by a customer last week who could not get the .NET Framework 1.1 to install correctly.  It reported an error while registering System.EnterpriseServices.dll just like I describe in this post.  In the end, the customer discovered that the system locale of the computer was set to Maltese, and he was able to install the .NET Framework by temporarily changing the system locale back to English.

    I did a little research, and found that there is a bug in the .NET Framework that causes it to not work correctly when the default system locale is set to a language that the .NET Framework does not recognize.  This bug has been fixed in the .NET Framework 1.0 SP3 and 1.1 SP1.  However, this bug causes the initial installation of the .NET Framework to fail and rollback, and you cannot install the service pack without first getting the product installed (unless you use a method like I describe here, which will work but is not "officially" supported).

    With the release of Windows XP SP2, Microsoft shipped Enabling Language Kits (ELKs) for 25 new locales (click here for a complete list and a nice description of what features ELKs provide).  Because of the bug in the .NET Framework that I described above, if a computer running XP SP2 has the system locale set to one of these 25 new locales, installation of the .NET Framework will fail while trying to register System.EnterpriseServices.dll (which happens to be the first time that managed code gets run during setup and therefore is the first time the bug is hit).

    If you are running into this bug on your Windows XP SP2 computer, you can use the following steps to work around this bug in the .NET Framework and get it installed:

    1. From the Start menu, type intl.cpl in the Run box or go to Control Panel and choose the Regional and Language Options item
    2. Click the Advanced tab
    3. Change the language in the dropdown box labeled "Select a language to match the language version of the non-Unicode programs you want to use:" to English (this setting represents the system locale for the computer)
    4. Check the box labeled "Apply all settings to the current user account and to the default user profile"
    5. Click OK
    6. Restart
    7. Install the .NET Framework 1.0 or 1.1
    8. Install .NET Framework 1.0 SP3 or 1.1 SP1
    9. Return to the Regional and Language Options control panel and change the language in the Advanced tab back to the original setting

    For reference, here is what the Advanced tab of the Regional and Language Options control panel looks like.  This screenshot is from my laptop, where I was able to reproduce the failure to install the .NET Framework by changing my system locale to Welsh (one of the 25 new ELKs included in XP SP2):
     

    Regional and Language Options control panel Advanced tab

    <update date="7/26/2005> As Michael Kaplan points out, the underlying bug affects both the .NET Framework core setup and the .NET Framework service pack setup.  Once a computer has .NET Framework 1.0 + SP3 and/or 1.1 + SP1, the bug will not affect any future .NET Framework service packs.  In addition, the bug can happen if your computer has a default user locale set to one of the new ELK languages, not just a default system locale. </update>

    <update date="4/17/2008"> Added a note indicating that the issue in this post can affect the .NET Framework 1.0 and 1.1 setup on Windows Vista and not just Windows XP SP2 </update>

     

  • Aaron Stebner's WebLog

    Example WiX-based setup that can be used to build both 32-bit and 64-bit MSIs

    • 20 Comments

    I previously posted an example that allows you to build a WiX-based MSI that will install a Windows Vista Media Center application and create a custom start menu strip.  However, there is a limitation in this example (that was pointed out in this post on the Media Center Sandbox discussion forum) that affects the ability to install the application on 64-bit operating systems.  This blog post describes the limitations in my previous sample and presents a modified version of that sample that will allow you to build both 32-bit and 64-bit MSIs in order to work around the limitations.

    Description of the problem with my previous example

    As this forum post describes, you have to directly set registry entries in order to add custom strips to the Media Center start menu (which means that you have to author RegistryKey and RegistryValue elements in WiX).  However, if you create a 32-bit MSI and then try to install it on a 64-bit OS, the registry entries will get written to the WOW64 hive (HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft).  The 64-bit version of Windows Vista Media Center looks in the 64-bit registry hive and not the WOW64 registry hive when looking for custom start menu strips to load.  Therefore, the custom start menu strip will not appear in the Media Center start menu on a 64-bit OS in my previous example.

    Example that can be used to solve this problem

    To solve this issue, it is necessary to create separate 32-bit and 64-bit installers.  It is a little bit tricky to configure all of the settings and attributes that are necessary to create a 64-bit MSI just by reading through WiX and Windows Installer documentation, so I decided to create a WiX 3.0-based example that can be used to build 32-bit and 64-bit MSIs from the same WiX source (WXS) file.

    You can download this example from http://cid-27e6a35d1a492af7.skydrive.live.com/self.aspx/Blog%7C_Tools/start%7C_menu%7C_strip%7C_setup%7C_example%7C_with%7C_64bit.zip.  I started from my previous 32-bit-only example, and added 64-bit build support.  While this sample happens to install a Windows Vista Media Center application, it is intended to help demonstrate the general concepts required to create 64-bit MSIs in WiX.

    Changes made in this example to enable 64-bit builds

    The new sample includes a single WXS file that is processed twice in order to build 2 different MSIs (one 32-bit and one 64-bit).  In order to create a single WXS file that can build both types of MSI, I introduced a WiX pre-processor variable to pass in the name of the processor architecture, and then I added some if/then/else blocks to conditionally set some of the necessary MSI attributes based on whether the MSI being created will be 32-bit or 64-bit.

    If you look in the setup.wxs file in the example I posted, you can see all of the changes that I made to enable building a 64-bit MSI by looking for sections of the file that are enclosed in if statements such as the following:

    <?if $(var.ProcessorArchitecture)=x64 ?>
        <Package Description="!(loc.Package_Description)" Comments="!(loc.Package_Comments)" InstallerVersion="200" Compressed="yes" Platforms="x64" />
    <?else ?>
        <Package Description="!(loc.Package_Description)" Comments="!(loc.Package_Comments)" InstallerVersion="200" Compressed="yes" />
    <?endif ?>

    In order to set the ProcessorArchitecture variable, I added the following command line parameter when calling candle.exe to compile the WXS file:

    "%WIX_BUILD_LOCATION%\candle.exe" setup.wxs -dProcessorArchitecture=%PROCARCH% -out "setup_%PROCARCH%.wixobj"

    In addition, I added a second set of commands to call candle.exe and light.exe twice - one with the ProcessorArchitecture value set to x86 and the other with the ProcessorArchitecture value set to x64.

    Specific differences between a 32-bit MSI and a 64-bit MSI

    The following are the changes that I made in order to be able to create both 32-bit and 64-bit MSIs in WiX:

    • I created a unique product code for the x64 MSI that is different from the x86 MSI
    • In the Package element, the Platforms attribute must be set to the proper 64-bit operating system so that Windows Installer will recognize it as a 64-bit MSI.  In my example, I am creating an x64 MSI, so I set the Platforms value to "x64" for the 64-bit MSI, and left it blank (the default value) for the 32-bit MSI
    • I created a different default directory structure for each processor architecture.  The 64-bit MSI will install under the ProgramFiles64Folder and the 32-bit MSI will install under the ProgramFilesFolder by default.  This is necessary because Windows Installer requires 64-bit components to install under a 64-bit directory by default
    • I created a unique set of 64-bit components by copying the original set of 32-bit components, updating the Id values to be different than the 32-bit Id values, creating unique Guid values and adding the element Win64="yes" to indicate that these components are 64-bit.  A component must be marked as Win64="yes" in order to cause registry entries to be written under the 64-bit registry hive instead of the WOW64 registry hive
    • In order to prevent the 32-bit MSI from installing on a 64-bit OS (which will work by default, but that we do not want to work once we have a specific 64-bit MSI to install on a 64-bit OS), I added a custom action to the 32-bit MSI and scheduled it in the InstallExecuteSequence and InstallUiSequence tables.  The custom action checks to see if the Windows Installer 64-bit property is set (which indicates that the MSI is being invoked on a 64-bit system), and if that is set, it will block the MSI from installing

    Where to read more about 64-bit issues related to Windows Installer

    When working on this example, I relied heavily on the information in this post on Heath Stewart's blog and the links to Windows Installer MSDN topics that are included in it.  If you are looking for more detailed information about how Windows Installer works behind the scenes in 64-bit scenarios, I encourage you to check out this blog post and also the other topics in Heath's 64-bit blog category.

    <update date="3/23/2009"> Fixed broken link to sample download location. </update>

     

  • Aaron Stebner's WebLog

    Updated versions of .NET Framework cleanup and verification tools with Windows 7 support

    • 19 Comments

    Over the past week or so, I’ve posted updated versions of both the .NET Framework Cleanup Tool and the .NET Framework Setup Verification Tool.  The primary reason for the updates is to address some specific problems using the tools on Windows 7.  I also fixed a few other issues that customers reported to me or that I discovered in my own testing.

    Here is a list of the changes made to each of the tools:

    .NET Framework Cleanup Tool changes (July 24, 2009):

    • Added logic to correctly cleanup the .NET Framework on Windows 7.  The .NET Framework 2.0 SP2, 3.0 SP2 and 3.5 SP1 are all installed as OS components on Windows 7, so the cleanup tool will not allow you to remove these versions of the .NET Framework on this OS.
    • Added detection and logging for the .NET Framework 4.  The cleanup tool does not yet support cleaning up the .NET Framework 4.  This will be added in a future release.
    • Prevent cleanup of mscoree.dll on Vista and higher.

    .NET Framework Setup Verification Tool changes (July 17, 2009)

    • Fixed false errors being reported for non-English versions of the .NET Framework 1.0.
    • Fixed filtering problem that caused the .NET Framework 1.0 to be removed from the list of available products if any 1.0 service packs are installed.
    • Fixed false errors being reported for the .NET Framework 1.1 if the .NET Framework 1.0 is also installed on the system.
    • Fixed false errors being reported for the .NET Framework 3.5 SP1 on Windows 7.
    • Added detection and logging for .NET Framework 4 and Windows 7.  The verification tool does not yet support verifying the .NET Framework 4.  This will be added in a future release.

    User’s Guides and Download Links

    Here are links to the user’s guides for each of the tools – there are links in each user’s guide that can be used to download the latest version of each tool:

    As always, please let me know (by posting a comment on one of my blog posts or sending me an email) if you run into any issues or have any questions using either of these tools.

  • Aaron Stebner's WebLog

    Issue installing the .NET Framework 3.5 or 3.5 SP1 on checked or pre-release builds of Windows Vista or Windows Server 2008

    • 53 Comments

    I have heard from a couple of customers who ran into issues installing the .NET Framework 3.5 and/or the .NET Framework 3.5 SP1 on one of the following OS types:

    • Checked (also known as debug) builds of Windows Vista and/or Windows Server 2008
    • Pre-release builds of Windows Vista and/or Windows Server 2008

    One of these customer reports can be found in this forum post.  I wanted to describe this scenario in more detail in case anyone else runs into a similar issue in the future.

    Description of the issue

    The .NET Framework 3.5 and 3.5 SP1 install service packs for the .NET Framework 2.0 and the .NET Framework 3.0 behind the scenes.  On Windows Vista and Windows Server 2008, the .NET Framework 2.0 and 3.0 service packs are installed as OS updates.  These OS updates are marked to only install on the final release versions of Windows Vista and Windows Server 2008.  That means that they will not allow you to install them on checked builds of these OS's, and they will also not allow you to install them on pre-release versions of these OS's.

    Here is the exact list of .NET Framework 3.5 installation scenarios that will fail on checked builds of the OS or pre-release builds of the OS:

    • Installing the .NET Framework 3.5 on the original release of Windows Vista (but not Windows Vista SP1 or later)
    • Installing the .NET Framework 3.5 SP1 on the original release of Windows Vista or Windows Vista SP1
    • Installing the .NET Framework 3.5 SP1 on Windows Server 2008

    However, installing the original release of the .NET Framework 3.5 on Windows Vista SP1 or Windows Server 2008 will not fail due to this issue.  This is because Windows Vista SP1 and Windows Server 2008 already include the .NET Framework 2.0 SP1 and 3.0 SP1 as OS components, so .NET Framework 3.5 setup does not need to install any OS updates on those systems.

    How to work around the issue

    Unfortunately, there is not a workaround that will allow you to install on a checked build or a pre-release build of Windows Vista or Windows Server 2008.  Instead, you will need to install a final release build of Windows Vista or Windows Server 2008, then re-run .NET Framework 3.5 or 3.5 SP1 setup.

    How to diagnose the issue

    If you try to install in one of the above configurations, you will see the following error in the .NET Framework 3.5 or 3.5 SP1 log file named %temp%\dd_dotnetfx35install.txt:

    [08/08/08,11:11:11] Microsoft .NET Framework 2.0SP1 (CBS): ***ERRORLOG EVENT*** : Error: Installation failed for component Microsoft .NET Framework 2.0SP1 (CBS). MSI returned error code 1.

    Error code 1 for Windows Vista or Windows Server 2008 OS update packages means that the package is not applicable on the current OS.

    Important note about error code 1 during .NET Framework 3.5 or 3.5 SP1 setup

    Please note that this blog post only describes one possible cause of error code 1 during .NET Framework 3.5 or 3.5 SP1 installation.  If you are not running a checked build of Windows or a pre-release version of Windows, then the issue described here is not the cause of the installation failure on your system.

    If you are running into error code 1 but are not running a checked or pre-release build of Windows, then it typically helps to review the .NET Framework 3.5 log files to try to learn more about the root cause of the issue.  You can find more information about what log files are produced by .NET Framework 3.5 setup in this blog post, and there is information in this blog post that describes options for reporting installation failures back to Microsoft for additional investigation.

    The logs that are typically the most useful in diagnosing error code 1 are the following:

    • %temp%\dd_dotnetfx35install.txt
    • %windir%\logs\cbs\cbs.log
    • %windir%\WindowsUpdate.log
  • Aaron Stebner's WebLog

    Possible cause of 1935 error with HRESULT 0x8002802F

    • 25 Comments

    A while back, I posted an article describing causes of many types of 1935 errors that have been seen in the past.  I wanted to talk about one specific type of 1935 error in a little more detail and provide information about a possible root cause that I did not describe in that previous article.

    A 1935 error in an MSI-based installations code is a catch-all for most of the possible assembly installation errors. In order to diagnose the problem in more detail, it is usually necessary to look at the verbose MSI log file.  In some cases, you will see an error like the following:

    Error 1935. An error occurred during the installation of assembly '<myAssembly>'. Please refer to Help and Support for more information. HRESULT: 0x8002802F. assembly interface: , function: CreateAssemblyNameObject, component: {A7A9D92E-C67F-4E96-BB90-5A4147DAEF6B}

    The key information needed to diagnose the exact root cause of a 1935 error is usually the HRESULT value listed in the verbose MSI log file.

    The HRESULT value listed above is 0x8002802F (-2147319761), and it means "function not defined in specified DLL." There are a few possible root causes of this issue. The most common cause is that the file %windir%\system32\mscoree.dll is missing, corrupt or an incorrect version. In most cases, repairing the highest version of the .NET Framework on the system will correct any problems related to mscoree.dll and will resolve the problem if this is the case.

    In a few less common cases, the file %windir%\system32\mscoree.dll is present, but registry values used by the .NET Framework to find and load specific versions of the .NET Framework are missing. The following values are required by mscoree.dll in order to load each version of the .NET Framework:

    For the .NET Framework 2.0 (on an x86 version of Windows):

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
    InstallRoot = C:\Windows\Microsoft.NET\Framework\

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\Upgrades]
    2.0.50727 = 1.0.0-2.0.50727

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\v2.0]
    50727 = 50727-50727

    For the .NET Framework 2.0 (on an x64 version of Windows):

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
    InstallRoot = C:\Windows\Microsoft.NET\Framework64\

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\Upgrades]
    2.0.50727 = 1.0.0-2.0.50727

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\v2.0]
    50727 = 50727-50727

    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]
    InstallRoot = C:\Windows\Microsoft.NET\Framework\

    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432NodeMicrosoft\.NETFramework\Policy\Upgrades]
    2.0.50727 = 1.0.0-2.0.50727

    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\Policy\v2.0]
    50727 = 50727-50727

    For the .NET Framework 1.1:

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
    InstallRoot = C:\Windows\Microsoft.NET\Framework\

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\Upgrades]
    1.1.4322 = 1.0.0.0 - 1.1.4322

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\v1.1]
    4322 = 3706-4322

    For the .NET Framework 1.0:

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
    InstallRoot = C:\Windows\Microsoft.NET\Framework\

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Policy\v1.0]
    3705 = 3321-3705

    If any of the above registry values are missing on your system, you will need to manually add them in order to resolve 1935 errors with HRESULT value 0x8002802F.  Note that the InstallRoot value must be set to the exact location of the %windir% folder on your system, so you may need to adjust that value from the one listed above if your %windir% is not located at c:\Windows.

    <update date="2/4/2008"> One of the values for the .NET Framework 1.0 was incorrect, so I fixed it </update>

    <update date="12/16/2009"> Added 64-bit registry information for the .NET Framework 2.0. </update>

     

  • Aaron Stebner's WebLog

    Where to find .NET Framework 2.0 SP1, 2.0 SP2, 3.0 SP1, 3.0 SP2, 3.5 and 3.5 SP1 setup log files

    • 18 Comments

    A while back, I posted a list of possible log files for .NET Framework 3.5 and Visual Studio 2008 setup.  Since then, I've realized that there are some sets of log files missing from that list, so I decided to create a separate blog post with information about setup log files that are specific to the .NET Framework 3.5 family of products.  This family includes the following:

    • .NET Framework 2.0 SP1 and SP2
    • .NET Framework 2.0 SP1 and SP2 language packs
    • .NET Framework 3.0 SP1 and SP2
    • .NET Framework 3.0 SP1 and SP2 language packs
    • .NET Framework 3.5 and 3.5 SP1
    • .NET Framework 3.5 and 3.5 SP1 language packs

    The following is a list of log files that can be produced by all of the above setup packages.  In all of the cases below, the logs are created by default, and you do not need to specify any verbose logging settings or registry values to cause the logs to be produced.  Also, you can find the %temp% directory by clicking on the Windows start menu, typing %temp% and pressing Enter.

    .NET Framework 2.0 SP1 and SP2 setup log files

    The following is a complete list of log files that can be produced during .NET Framework 2.0 SP1 and SP2 setup.  This list may vary depending on what OS you are installing on, what processor architecture, and what prerequisite components were already installed on the system prior to running .NET Framework 2.0 SP1 and SP2 setup.

    Logs produced by the .NET Framework 2.0 SP1 and SP2 setup wrapper:

    • %temp%\dd_dotnetfx20install*.txt
    • %temp%\dd_dotnetfx20error*.txt
    • %temp%\dd_depcheck_netfx20*.txt

    Logs produced by the packages chained during .NET Framework 2.0 SP1 and SP2 setup:

    • .NET Framework 2.0 SP1 and SP2 verbose MSI log - %temp%\dd_net_framework20*.txt
    • .NET Framework 2.0 SP1 and SP2 language pack verbose MSI log - %temp%\dd_NET_Framework*20*LP*.txt

    .NET Framework 3.0 SP1 and SP2 setup log files

    The following is a complete list of log files that can be produced during .NET Framework 3.0 SP1 and SP2 setup.  This list may vary depending on what OS you are installing on, what processor architecture, and what prerequisite components were already installed on the system prior to running .NET Framework 3.0 SP1 and SP2 setup.

    Logs produced by the .NET Framework 3.0 SP1 and SP2 setup wrapper:

    • %temp%\dd_dotnetfx30install*.txt
    • %temp%\dd_dotnetfx30error*.txt
    • %temp%\dd_depcheck_netfx30*.txt

    Logs produced by the packages chained during .NET Framework 3.0 SP1 and SP2 setup:

    • RGB Rasterizer - %temp%\dd_RGB9Rast_*.txt
    • MSXML 6.0 - %temp%\dd_msxml6_*.txt
    • WIC - %temp%\dd_wic*.txt
    • .NET Framework 2.0 SP1 and SP2 verbose MSI log - %temp%\dd_net_framework20*.txt
    • .NET Framework 2.0 SP1 and SP2 language pack verbose MSI log - %temp%\dd_NET_Framework*20*LP*.txt
    • .NET Framework 3.0 SP1 and SP2 verbose MSI log - %temp%\dd_net_framework30*.txt
    • .NET Framework 3.0 SP1 and SP2 ServiceModelReg.exe custom action - %temp%\dd_wcf_retCA*.txt
    • .NET Framework 3.0 SP1 and SP2 language pack verbose MSI log - %temp%\dd_NET_Framework*30*LP*.txt

    .NET Framework 3.5 and 3.5 SP1 setup log files

    The following is a complete list of log files that can be produced during .NET Framework 3.5 and 3.5 SP1 setup.  This list may vary depending on what OS you are installing on, what processor architecture, and what prerequisite components were already installed on the system prior to running .NET Framework 3.5 and 3.5 SP1 setup.

    Logs produced by the .NET Framework 3.5 and 3.5 SP1 setup wrapper:

    • %temp%\dd_dotnetfx35install*.txt
    • %temp%\dd_dotnetfx35error*.txt
    • %temp%\dd_depcheck_netfx_*.txt

    Logs produced by the packages chained during .NET Framework 3.5 and 3.5 SP1 setup:

    • RGB Rasterizer - %temp%\dd_RGB9Rast_*.txt
    • MSXML 6.0 - %temp%\dd_msxml6_*.txt
    • WIC - %temp%\dd_wic*.txt
    • .NET Framework 2.0 SP1 and SP2 verbose MSI log - %temp%\dd_net_framework20*.txt
    • .NET Framework 2.0 SP1 and SP2 language pack verbose MSI log - %temp%\dd_NET_Framework*20*LP*.txt
    • .NET Framework 3.0 SP1 and SP2 verbose MSI log - %temp%\dd_net_framework30*.txt
    • .NET Framework 3.0 SP1 and SP2 ServiceModelReg.exe custom action - %temp%\dd_wcf_retCA*.txt
    • .NET Framework 3.5 and 3.5 SP1 verbose MSI log - %temp%\dd_net_framework35*.txt
    • .NET Framework 3.5 and 3.5 SP1 language pack verbose MSI log - %temp%\dd_NET_Framework35_LangPack*.txt

    Setup log files for other .NET Framework products

    I have written separate blog posts about log file locations for other .NET Framework products not listed above.  Here they are for your reference in case you need them:

    <update date="8/24/2008"> Updated list of .NET Framework 3.0 SP1 log files </update>

    <update date="4/13/2009"> Clarified that the list of logs in this post is applicable to 2.0 SP2, 3.0 SP2 and 3.5 SP1 as well. </update>

     

  • Aaron Stebner's WebLog

    Updated sample .NET Framework detection code that does more in-depth checking

    • 19 Comments

    I previously posted some sample code to detect the version(s) and service pack levels of the .NET Framework that are installed on a computer (here and here).  The original version of the sample code that I wrote queries the officially documented registry values that are used to detect the presence of each specific version of the .NET Framework.

    Since I posted this sample code, I have heard feedback from some customers who are including the .NET Framework as part of their setup packages.  They indicated that sometimes this code reports false positives - in other words, the sample returns true for a specific version of the .NET Framework but it isn't actually installed on the system.  I have seen this a couple of times in the past as well, and the root cause was that some of the registry entries used to detect the .NET Framework were orphaned on the system after an uninstall or OS reinstall scenario.

    In order to help address this type of issue, I've created a new version of the sample code that adds some new checks to help guard against orphaned registry values.  The logic it uses is to query the registry values like the previous sample used to, and then to supplement that with an additional check that loads mscoree.dll and uses some of its APIs to query for the presence of specific versions of the .NET Framework.  The underlying algorithm for this mscoree.dll-based check came from Junfeng Zhang and from a sample published on MSDN.

    This algorithm should prove more reliable in detecting whether or not a specific version of the .NET Framework is installed on the system because it does not rely solely on the registry.  In addition, it provides the side benefit of performing a quick health check for the .NET Framework itself because it attempts to invoke some APIs in the runtime.

    The new sample code contains the following specific changes from the previous version that I published:

    • Added the CheckNetfxVersionUsingMscoree and GetProcessorArchitectureFlag functions
    • Added logic in WinMain to call CheckNetfxVersionUsingMscoree in addition to the original calls to check .NET Framework registry data
    • Updated the code to use strsafe.h functions for string manipulations

    You will need the following in order to compile this sample:

    Please let me know if you have any trouble building or running this sample or incorporating it into your product setup logic.

    <update date="5/29/2009"> Fixed broken link to the sample code. </update>

     

  • Aaron Stebner's WebLog

    Finding Windows Installer help documentation (AKA where did MSI.chm go?)

    • 17 Comments

    I received an email yesterday from an individual who had just installed the latest Windows Installer Platform SDK and had read a previous blog post that I wrote about using msi.chm for Windows Installer help information, but was unable to find msi.chm on his system.  I took a look on our internal products server and couldn't find msi.chm there either, so I decided to go to the Platform SDK site and figure out what was going on.  What I found is that I was basing the information in that blog entry about msi.chm on what appears to be an older version of the Platform SDK that I had downloaded a while ago and then just copied msi.chm off to a separate location.

    I tried out a new download of the Windows Installer part of the Platform SDK, and it appears they have re-organized the help documentation for the entire SDK.  Instead of having standalone CHM files for each product in the SDK, there is now a unified Platform SDK help collection and each individual product plugs in and registers an HXS (compiled help) file.

    So what I had to do was launch the Platform SDK Documentation link on the Start menu after installation of the SDK.  From there I was able to use the index and search that I normally use in my old copy of msi.chm, and as an added bonus there are updated topics for Windows Installer 3.0 and some of the incorrect info in my old version of msi.chm have been fixed.

    Sorry for any confusion I created in my original post....

     

  • Aaron Stebner's WebLog

    Steps that might help fix Windows Update errors and a blank Windows Features dialog in Windows Vista

    • 6 Comments

    Over the holidays, I was asked by a friend to look at a problem they were running into on their Windows Vista system.  They were unable to connect to Windows Update and check for updates and received a cryptic error message.  After a few minutes of poking around on the system, I recognized a common set of symptoms that I had also seen on a couple of co-workers' systems a few weeks prior to that.  I also recognized some symptoms that I've heard about from customers via my blog who had trouble getting the .NET Framework 3.5 to install on Windows Vista due to issues with the .NET Framework 2.0 SP1 and/or .NET Framework 3.0 SP1 OS update packages that it tries to install behind the scenes.

    Since I had a system available to debug on, I ran through some troubleshooting steps that I've learned over the past couple of years related to Windows Vista OS update installation issues and identified several specific symptoms, and then eventually came up with a set of steps to fix this system.  Then I came back to work after the holidays and tried out the steps on my co-workers' systems and found that the same basic set of symptoms and resolution steps worked there as well.  As a result, I'm going to try to summarize these symptoms and the steps I used to resolve them in the hope that they might be helpful to others suffering from the same issues on their systems.

    Symptoms of this problem

    In the systems I've been able to find so far with this type of problem, I've observed a common set of symptoms.

    Symptom 1: Blank Windows Features dialog

    Going to the Programs and Features control panel and then clicking the link on the left labeled Turn Windows features on or off brings up the Windows Features dialog.  This can also be launched directly by running OptionalFeatures.exe.  In the error cases I've seen, the Windows Features dialog appears completely empty instead of listing all of the Windows components that can be enabled or disabled on the system.

    Symptom 2: Blank list of installed updates

    Going to the Programs and Features control panel and then clicking the link on the left labeled View installed updates brings up a list of installed service packs, updates and hotfixes for the OS and any applications installed on the OS.  In the error cases I've seen, the list of installed updates was completely empty, even when I knew for sure that some OS updates had been installed on the system.

    Symptom 3: Error when attempting to check for updates using Windows Update

    Going to the Windows Update control panel and choosing the Check for updates link either reports an error message and an HRESULT code (for example, 0x80070005 or 0x80073712) or states that there were no updates available for the system.

    Symptom 4: Hang or error when attempting to manually download and install OS updates

    Bypassing the Windows Update control panel by going to the Microsoft support site and directly downloading and attempting to install a Windows OS update package results in the update hanging and failing to complete installation or the update reporting that it is not applicable on the current OS and exiting without installing.

    I saw the latter behavior for the .NET Framework 3.5 on systems in this state.  On Windows Vista, the .NET Framework 3.5 attempts to install the .NET Framework 2.0 SP1 OS update package (because the .NET Framework 2.0 is an OS component on Vista).  When the systems I observed were in this broken state, the .NET Framework 2.0 SP1 failed to install, and I observed the following error in the .NET Framework 3.5 or 3.5 SP1 log file named %temp%\dd_dotnetfx35install.txt:

    [08/08/08,11:11:11] Microsoft .NET Framework 2.0SP1 (CBS): ***ERRORLOG EVENT*** : Error: Installation failed for component Microsoft .NET Framework 2.0SP1 (CBS). MSI returned error code 1.

    Error code 1 from the .NET Framework 2.0 or 3.0 CBS package means that the package is not applicable on the current OS.

    Steps that might help resolve this problem

    On the systems that I have been able to find in this state so far, I have used the following set of steps to get the system back into a working state so that it could display information in the Windows Features dialog, check for updates using Windows Update and successfully install OS updates.  I have only been able to work with a few systems in this broken state though, so I'm not sure the same set of steps will always work.  I wanted to post them here in case there are helpful in some cases though, but please keep in mind that your mileage may vary.

    1. Download the System Update Readiness Tool and save the .msu file to your desktop.  You need to make sure to download the correct version of this tool because there is a different version for each OS type and processor architecture.  You can find the download links for this tool in this knowledge base article.

    2. Run the System Update Readiness Tool.  Once you download the appropriate .msu file for your OS type and processor architecture, you can double-click on it to install it.  This tool is not an OS update, but it uses the .msu packaging logic that OS updates use.  Therefore, it will tell you that it is installing the package, but it is actually running the tool in the background.  When the tool is running, you will see processes named checksur.exe, checksurlauncher.exe and checksurpackage.exe listed in Task Manager.

      Note: The tool attempts to fix any problems that it finds on the system.  However, it was not able to fix the problems it found on the systems that I have seen that experienced this type of problem.  It is still useful to run the tool in order to create a log file that lists the issues it finds.

    3. Look at the output in the CheckSUR.log file and make fixes based on what the tool reports.  The checksur.exe tool created a log file at the following location: %windir%\Logs\CBS\CheckSUR.log.  On the systems that I have seen this type of problem on, the CheckSUR.log reported problems with some of the registry values located under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages on the system.  I used the information in CheckSUR.log to locate and manually delete keys with errors reported for them.  On one of the systems, some of the sub-keys only had permissions assigned to them for the local system account, so I had to add the Administrators group and then delete them.  On one of the other systems, some of the sub-keys were reported as orphaned from some previous OS update that had been installed on the system, so I manually deleted them.

      One very important note here - I strongly recommend making a backup of your registry before trying to manually change any of the sub-keys under this HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages key.  This sub-key contains information that is usually only modified by installing and uninstalling OS update packages, so it is possible to cause problems with the OS if you delete keys that are still needed.  If you do not feel comfortable manually backing up and modifying your registry, then I instead recommend that you try to repair your OS by re-running OS setup using your original OS installation disc.

    Note - I found another blog post with a more detailed step-by-step description about how to fix the Component Based Servicing registry keys.  You can find that post at http://www.raymond.cc/blog/archives/2009/03/06/fix-blank-or-empty-list-in-vista-turn-windows-features-on-or-off-optionalfeaturesexe/.

    Hopefully this set of steps will be helpful to some folks who run into this type of symptoms on their Windows Vista systems.  Again, I want to emphasize that I've only been able to directly look at a few systems that exhibited this type of symptoms, so these steps may or may not help 100% of the time if you have a system in a similar state.

    <update date="2/11/2009"> Updated list of steps to run the CheckSUR tool because the packaging for the tool has changed since the time I originally wrote this blog post. </update>

    <update date="4/3/2010"> Added a link to a blog post with additional steps about how to fix the Component Based Servicing registry keys. </update>

     

  • Aaron Stebner's WebLog

    How to create an installable layout for the final release of the .NET Framework 3.5

    • 25 Comments

    Back when the .NET Framework 3.5 beta 2 was released, I posted this item on my blog describing how to download the individual pieces of the .NET Framework 3.5 beta 2 in order to create an installable layout that can be used to create an installer that includes the .NET Framework 3.5 or for network deployment.  If you have looked at those instructions, you'll notice how long, tedious and potentially error-prone they are.

    Fortunately, as Bret Grinslade noted in this blog post, in the final release of the .NET Framework 3.5, a new package is available for download that includes all of the pieces of the .NET Framework 3.5 so that you no longer need to download the pieces individually in order to assemble an installable layout.

    The combined installation package for the .NET Framework is available for download at http://download.microsoft.com/download/6/0/f/60fc5854-3cb8-4892-b6db-bd4f42510f28/dotnetfx35.exe.

    After downloading this package, you can extract the contents by running dotnetfx35.exe /x and it will prompt you with a location to extract the contents to.  From there, you can trim down the installer payload if appropriate in your deployment scenario in the following ways:

    • If you do not plan to support installing on Windows Vista at all or plan to require Windows Vista SP1 in your scenarios (which will include the .NET Framework 2.0 SP1 and 3.0 SP1 so they do not have to be installed separately), you can remove the MSU files in the dotNetMSP folder
    • If you only plan to support installing on Windows Vista or later, you can remove the dotNetFX20 and dotNetFX30 folders.  These folders contain the .NET Framework 2.0 SP1 and .NET Framework 3.0 SP1 packages that are used on Windows XP and Windows Server 2003
    • If you plan to only support specific processor architecture(s), you can remove the appropriate payload for the processor architectures you do not plan to support (ia64, x64 or x86)

    Now you can run dotnetfx35setup.exe from the extracted folder to start installing the .NET Framework 3.5.

    One important note - if you decide to optimize your installer payload using any of the suggestions above, and it turns out that you over-optimized and setup really does need one of the packages that you deleted from the extracted folder, then .NET Framework 3.5 setup will attempt to automatically download the package for you if you have a live Internet connection during setup.  If it needs to download a package and the system does not have a live Internet connection, then .NET Framework 3.5 setup will fail to install.

  • Aaron Stebner's WebLog

    Installing an assembly to the GAC and the local file system

    • 23 Comments

    Some products require that assemblies be installed to both the global assembly cache (GAC) and to the local file system.  Windows Installer has native functionality that allows a setup author to do both.  You can author an assembly as a global assembly (which will cause Windows Installer to install the file to the GAC) by adding it to the MsiAssembly and the MsiAssemblyName tables of the MSI and setting the File_Application column of the MsiAssembly table to Null.  You can author an assembly as a private assembly (which will cause Windows Installer to install the file to the local file system) by adding it to the MsiAssembly table and setting the File_Application column to a file entry from the File table of the MSI.  Windows Installer will take the file entry, look up the component that owns it and then use the directory entry associated with that component to install the private assembly to that same directory.

    One of the first questions that comes up when a setup developer is trying to install an assembly to multiple locations is how to author the data in the MSI to install the same assembly component to both the GAC and the local file system.  In most cases where a setup needs to install the same file to multiple locations, you can use the DuplicateFile table.  Unfortunately, the DuplicateFile table does not support installing an assembly as both a global and a private assembly.  In other words, you have the option to indicate that an assembly is a private assembly or a global assembly, but not both.  In order to install the assembly to both the GAC and the local file system, you will have to create a second component and author one component as a global assembly and the other component as a private assembly.

    We have to install assemblies to both locations as part of the .NET Framework and Visual Studio setups.  In the case of the .NET Framework, the underlying architecture requires that the assemblies that are part it be installed to the GAC (for 3rd party applications) and to the local file system (for design-time scenarios in Visual Studio).  However, we had to carry 2 copies of each assembly in the setup package in order to install to both places because Windows Installer doesn't support using the DuplicateFile table to do this.  Carrying 2 copies of each assembly caused the overall size of the .NET Framework 1.0 and 1.1 redistributable setup package to grow even larger than it already was.  After looking at a lot of different options, we decided to implement a custom action solution in .NET Framework 2.0 that would manage the installation of assemblies to both the GAC and the local file system.  This allowed us to only carry a single copy of each file in the setup package and reduce the overall size of the .NET Framework setup by about 5 megabytes.  Of course, if you compare the size of dotnetfx.exe between versions 1.1 and 2.0 you won't see much of a difference.  What ended up happening was that the size of the features added in .NET 2.0 roughly cancelled out the size of the assemblies that we were carrying duplicate copies of in .NET 1.1.

     

  • Aaron Stebner's WebLog

    Reverse engineering a setup - lesson 1 - .NET Framework 1.1

    • 10 Comments

    Hey all, as I promised a while back, I wanted to walk through some examples of how I approach reverse engineering a setup package to learn how it works, make any necessary changes, figure out command line switches, etc.  I apologize for not posting anything in a while, I was spending some time with my family who was in town from Texas and then I managed to get sick right after they left.  But I'm back now  :-)

    I'm going to start with a relatively straight-forward reverse engineering example - the .NET Framework 1.1 package.  I chose this first because that setup is very simple - no setup data files, no configurable setup UI options, etc.  Yet it is complicated enough to be interesting and it is a setup that a lot of people want to include in their setup packages and/or have had issues trying to install.  I'm going to try to approach this from the perspective of someone who is familiar with different types of setup technologies in a broad sense, but who has not yet seen this particular setup before (I may get a little off track on this part because I'm so familiar with this setup from my previous work, but I'll try.....)


    Step 1 - figure out what packaging technology is being used

    When I download the .NET Framework 1.1 I see that it is a single EXE named dotnetfx.exe.  When I double-click on it, setup asks me if I want to install and when I say Yes it proceeds to extract files to the %temp% folder on my machine.  Then a EULA appears.  When I go to %temp% after the EULA appears, I see a folder named ixp000.tmp.  This tells me that the package in question is an IExpress self-extracting EXE.  Since I know it is IExpress, I can now use some well-known IExpress command lines to extract the package to a folder of my choosing.  I will run dotnetfx.exe /t:c:\aaron /c to create a folder named c:\aaron on my machine and unpack the .NET Framework files to this folder.  The /t flag specifies the folder to extract to, and the /c flag specifies that I want to extract the files only and not run the setup after extraction.

    Side note for setup developers - I found some IExpress docs on the web here, and you can also find iexpress.exe in %windir%\system32 on an XP Professional machine.  It is a useful tool for packaging up multiple files into a single package but it is also a fairly old technology and has some limitations that may not make it practical to use, depending on your scenario.

    Step 2 - figure out what setup/installation technology is being used

    Now that I have extracted the files, I will go to the c:\aaron folder that I created above.

    • The first thing I see in the folder is a file named netfx.msi - this tells me that the setup is a Windows Installer-based setup.
    • I see a file named netfx1.cab, and opening it in a file extraction utility such as WinZip, or in Windows Explorer on Windows XP or higher shows me that there are 204 files with long funny looking names inside.  My knowledge of Windows Installer tells me that these are the files that will be installed by netfx.msi because I know that if you install files from a CAB file using Windows Installer, you are required to name files in the cab using the File token from the File table of the MSI - hence the funny names.
    • There are 2 self-extracting EXE files named instmsi.exe and instmsiw.exe, and I recognize those as the setup packages for Windows Installer itself.  This means to me that this setup will install the required version of Windows Installer for the user if it is not already present on the machine.
    • Finally, I see a file named install.exe.  Initially I am not sure what this is for, but I guess that it is a bootstrapper EXE that will launch netfx.msi and will also launch instmsi.exe or instmsiw.exe if it is needed.  Out of curiousity, I run install.exe /? and observe the usage information that appears and it does indeed appear to be a .NET Framework setup bootstrapper.

    Step 3 - figure out the basics of how the setup works

    Most of the information I need to figure out how the setup works will be gained by installing Orca and then looking at the MSI, but first I want to look at a basic overview of what the setup is doing.  I will start by double-clicking install.exe - when I do so, the .NET Framework setup starts and the EULA appears.  Now I will take a look in the %temp% directory and see if the setup happens to be creating a log file since most setups will create some kind of log for debugging and troubleshooting.  I can sort the %temp% directory by Date Modified, and I see a log named dotnetfx.log there.  Opening this up and reading it gives me some ideas of what the install.exe process is doing - it is checking several system requirements such as OS type, OS service pack, Internet Explorer version, MDAC version.  It is also loading msi.dll to determine the version of Windows Installer on my system - this must be how it decides whether or not to run instmsi.exe/instmsiw.exe.  There is also a call to a function called StopDarwinService.  I'm not sure why this is here, but I know that Darwin is a code word for Windows Installer, and I know that on Windows NT-based OS's Windows Installer is actually a service instead of just an application, so I am guessing that install.exe is trying to stop the Windows Installer service before starting installation of the .NET Framework.

    After I look at all of this, I go ahead and step through the UI and install the .NET Framework 1.1, and then re-open the log file dotnetfx.log.  I see that it lists the command line that is passed to the MSIInstallProduct function - and I know that this is an API call for an application to install a product using Windows Installer.  Then I see a return code for that API call - fortunately it is 0 in this case to tell me that the .NET Framework 1.1 installed correctly.  Then I see another call to StopDarwinService, so this install.exe application is stopping the Windows Installer service again after installation is complete - kind of strange.

    Step 4 - figure out details about how the setup works

    Now that I have a basic understanding of how the .NET Framework 1.1 setup works, I'm going to use my Windows Installer expertise to dig a little deeper.  The first thing I will do is install Orca, then right-click on netfx.msi and choose Edit with Orca to view the contents of the MSI.  There is a ton of data to wade through in an MSI and it is overwhelming at first, so I will only look at a few key things here:

    • Go to the property table and look at the product code, upgrade code, and any other interesting properties that are set.  Most of the properties in this table will be standard data documented in msi.chm, but sometimes there may be interesting custom properties set here.
    • Go to the Tools menu and see if the Dialog Preview item is enabled.  If it is, that means that this setup package uses UI that is contained in the MSI itself.  For the .NET Framework 1.1, it is enabled and we can look at all of the possible UI screens.  If you look closely at the Dialog Preview and cross reference it with data in the UI tables of the MSI (the Control, ControlEvent, and Dialog tables among others), you can find a bug in this setup.  The ActionDialog is shown during installation, and it has a Control_Default set to cancel which means that if you press Enter with this dialog on-screen it will trigger the cancel action.  However, an MSI-based setup should not allow you to cancel if it reaches the commit phase of setup (which is normally distinguished by the cancel button being greyed out or disappearing from the setup UI progress screen).  However, for the .NET Framework 1.1, you can press Enter even when the cancel button is gone and it will trigger the cancel action.
    • Go to the InstallUISequence table and observe the conditions and order of actions when running the setup with full setup UI
    • Go to the AdminUISequence table and observe the conditions and order of actions when running the setup in administrator mode.  This is often the source of some bugs if someone forgets to author an action or condition on the AdminUISequence table but it exists in the InstallUISequence - this will cause behavior differences for setup depending on whether or not it is run in admin mode.
    • Go to the InstallExecuteSequence table and observe the conditions and order of actions when setup is actually installing/uninstalling
    • Go to the LaunchCondition table and see if there are any actions that will block setup from installing.  In the case of the .NET Framework 1.1, it will block installation if the OS being installed to is 64-bit.
    • Go to the Component table and observe the attributes and conditions for components to be installed.  In the case of the .NET Framework 1.1 - some files will not install on certain OS types (for example, ASP.NET is not supported on OS's before Windows 2000).  Also, all files have at least an attribute of 8 meaning that Windows Installer will respect and increment/decrement the legacy shared DLL refcounting scheme for these files.  In addition, files that have OS conditions have the attribute of 64 (= transitive), which means that Windows Installer will re-evaluate component conditions when a repair is attempted.  This is nearly always needed for files with OS conditions because we want to have the files added or removed as appropriate when performing a repair after an OS upgrade or downgrade.  For example - if you install the .NET Framework 1.1 on Windows 98/ME then upgrade to Windows XP and then perform a repair, we want the ASP.NET files to be installed for the user.

    There are many more things that we could look at in an MSI, but the above are good starting points.  Often for other setups you will see items in tables that will lead you on trails through other tables.  Most commonly, if there are launch conditions that depend on the existence of other applications, you will be led to the AppSearch table to figure out exactly what file or registry data the setup is looking for when deciding whether or not to block.

    Step 5 - install with verbose logging and look at the MSI log file

    Reading an MSI log file is more of an art than a science but can often be useful when reverse engineering a setup.  For the .NET Framework 1.1, we know that because it is an MSI we can set the verbose logging flags before running setup - HKLM\Software\Policies\Microsoft\Windows\Installer, Debug (REG_DWORD = 7) and Logging (REG_SZ = voicewarmup!).  These will give us a verbose log named msi*.log in %temp% where * is a randomly generated set of characters.

    I also noticed when running install.exe /? it says that if you pass a /l flag it will generate netfx.log in %temp%.  Since I also noticed that the log created by running install.exe was named dotnetfx.log and not netfx.log, I might be curious what the difference is and run install.exe /l from c:\aaron to see what it does.  When I install this way I see that the resulting file %temp%\netfx.log is essentially the equivalent of a Windows Installer verbose log file without needing those registry keys to be set.  So now I can take a look at netfx.log (or msi*.log if I choose) and view the step-by-step process of this setup.


    With that, the process of reverse engineering the .NET Framework 1.1 setup is done for the common cases.  There is of course more detail that may be needed depending on your scenarios, but much of that will require more in-depth analysis of the MSI tables and/or the verbose MSI log files.  I will leave that for a later lesson.

    Side note for the curious - the reason that the .NET Framework 1.1 setup stops the Windows Installer service is because Windows Installer uses pieces of the .NET Framework to install assemblies to the GAC (the MSIAssembly and MSIAssemblyName tables in the MSI) in Windows Installer 2.0 and higher.  This creates a classic chicken-n-egg problem - Windows Installer is going to install the .NET Framework but Windows Installer needs the .NET Framework in order to do so.  Because of that, Windows Installer has some special logic to bootstrap the part of the .NET Framework it needs to install assemblies, but since Windows Installer is run as a service, it could already be running from a previous setup and we want to stop the service to unload any older versions of the .NET Framework from memory so that the most recent version will be used.

    I hope this post is at least a little bit useful to give some insight into how I approach the process of taking apart a setup and figuring out how it works.  I will post more later with a more complicated example of a setup that uses information from data files, etc.  Let me know via comments or emails if you have any questions about any of the above.....

  • Aaron Stebner's WebLog

    How to install VS 2005 and MSDN for VS 2005 on XP without SP2

    • 38 Comments

    Microsoft has an internal program for testing hotfixes that apply to Windows XP SP1 that asks some employees to not install XP SP2.  Some of the people in this program have wanted to install VS 2005 and when they tried, they ran into the blocks in VS setup that require XP SP2 to be installed.  VS 2005 setup does not have any technical requirements on XP SP2, but the block is in place to encourage everyone to upgrade to SP2, and also to reduce the test matrix.  If you are running into this block and really need to install VS 2005 on a system that is running Windows XP without SP2, you can use the following steps.  Please note that these steps are not officially supported and I would recommend installing XP SP2 before installing VS 2005 if at all possible:

    1. Navigate to the setup subfolder on the VS 2005 DVD and run VS 2005 as follows to skip all prerequisite checks - setup.exe /NO_BSLN_CHECK

    Important note - if you use the above option, none of the prerequisites for Visual Studio 2005 will be installed.  You need to make sure to manually pre-install Windows Installer 3.1, the .NET Framework 2.0 and the MSXML 6.0 Parser using the setup packages located in the wcu subfolder on the VS 2005 DVD.  Failure to do so will result in errors during the VS installation process.

    -or-

    1. Launch regedit.exe
    2. Go to HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Windows
    3. Change the CSDVersion value to be 512 or higher (0x0000200 in hexadecimal)
    4. Close regedit.exe and install Visual Studio 2005
    5. Rerun regedit.exe and change the CSDVersion value back to what it was originally

    Once VS 2005 is installed, you will run into a separate block while trying to install MSDN.  To workaround this, you can use the same registry-based workaround listed above, or do the following:

    1. Install Orca if you haven't already (you can get a copy here without downloading the whole Windows Installer PSDK)
    2. Copy the contents of the VS 2005 DVD to your computer
    3. Right-click on the file msdn.msi and choose Edit with Orca
    4. Go to Launch condition table and remove the row with the following data in the condition column: "(VersionNT>501) OR (VersionNT=500  AND ServicePackLevel>3) OR (VersionNT=501  AND ServicePackLevel>1)    The minimum operating system requirement is Windows 2000 SP4,  Windows XP SP2, or Windows Server 2003"
    5. Save and close msdn.msi
    6. Install MSDN from the local copy

    Note: after changing the CSDVersion registry key or modifying msdn.msi using Orca, you will need to use the following command line to install MSDN:  msiexec /i msdn.msi SETUP_EXE=yes

    <update date="8/26/2005"> I didn't specify clearly enough when I posted this last night that these steps are not "officially" supported, I must have been a little tired and left off the disclaimer I normally write when I post tips like this.  I've added it above.

    <update date="11/8/2005"> After receiving email from Fabrice based on the comments posted here, I realized that there is an additional step needed to install MSDN after using the workarounds listed above.  I've updated the steps accordingly </update>

    <update date="4/5/2006"> Added a caveat to option 1 above that you must manually install prerequisites in order to use this option </update>

     

  • Aaron Stebner's WebLog

    Building an MSI using WiX v3.0 that includes the VC 8.0 runtime merge modules

    • 17 Comments

    I was recently asked a question by a customer who was building an MSI using WiX v3.0 and the Votive add-in for Visual Studio 2005.  They were trying to consume the VC 8.0 runtime merge modules (MSMs) into their MSI, but were having trouble figuring out exactly how to configure their WiX project so that it would correctly consume these MSMs and install the VC 8.0 runtime files as part of their MSI-based setup.

    I looked around a little bit and found these instructions written by Nikola Dudar on the Visual C++ team here at Microsoft.  However, the instructions in that blog post are based on WiX v2.0, and the equivalent steps in WiX v3.0 are much more straightforward, so I decided to post a set of steps that can be used to create an MSI in WiX v3.0 and Votive that consumes the VC 8.0 runtime MSMs:

    1. Install Visual Studio 2005 Standard Edition or higher
    2. Download and install the latest build of WiX 3.0 from http://wix.sourceforge.net/downloadv3.html.  You need to install the ProjectAggregator2 MSI and then the WiX 3.0 MSI
    3. Launch Visual Studio 2005
    4. Choose File | New | Project...
    5. In the New Project dialog, select the WiX project type and then the WiX Project template to create a new WiX project
    6. In the WXS file that is created as part of the new project, add new <Merge> elements as children of the TARGETDIR <Directory> element for each one of the VC 8.0 runtime merge modules that you want to include in your MSI.  For example, to include MSVCRT, use the following items:

      <Merge Id="CRT" Language="0" SourceFile="c:\Program Files\Common Files\Merge Modules\microsoft_vc80_crt_x86.msm" DiskId="1" />


      Note: You will need to change the SourceFile attributes to point to the exact locations of the MSM file on your system.  This location depends on what partition you have your OS installed to.

    7. For each <Merge> element that you addded in step 6, add a <MergeRef> element under the appropriate <Feature> element.  For example:

      <MergeRef Id="CRT" />

    8. Add any other information that you want to include in your MSI, save the project and build it using Visual Studio

    When building an MSI that consumes the VC 8.0 runtime MSMs using Votive v3.0 in Visual Studio 2005, you may see several of the following types of warnings in your build output:

    1. WixProject1.wxs(10,0): Warning LGHT1055: The InstallExecuteSequence table contains an action 'SxsInstallCA' which cannot be merged from the merge module 'c:\Program Files\Common Files\Merge Modules\policy_8_0_Microsoft_VC80_ATL_x86.msm'. This action is likely colliding with an action in the database that is being created. The colliding action may have been authored in the database or merged in from another merge module. If this is a standard action, it is likely colliding due to a difference in the condition for the action in the database and merge module. If this is a custom action, it should only be declared in the database or one merge module.
    2. light.exe(0,0): Warning LGHT1076: ICE03: String overflow (greater than length permitted in column); Table: Component, Column: KeyPath, Key(s): downlevel_manifest.8.0.50727.762.98CB24AD_52FB_DB5F_FF1F_C8B3B9A1E18E
    3. light.exe(0,0): Warning LGHT1076: ICE30: The target file 'ansiatl.dll|ATL80.dll' might be installed in '[SystemFolder]' by two different conditionalized components on an LFN system: 'ansi_atl80.97F81AF1_0E47_DC99_FF1F_C8B3B9A1E18E' and 'nosxs.97F81AF1_0E47_DC99_FF1F_C8B3B9A1E18E'. If the conditions are not mutually exclusive, this will break the component reference counting system.
    4. light.exe(0,0): Warning LGHT1076: ICE82: This action SystemFolder.97F81AF1_0E47_DC99_FF1F_C8B3B9A1E18E has duplicate sequence number 6 in the table InstallExecuteSequence
    5. light.exe(0,0): Warning LGHT1076: ICE83: The keypath for Global Win32 SXS Assembly (Component_=uplevel.66332652_9C28_58B1_FF1F_C8B3B9A1E18E) SHOULD NOT be it's manifest file for assemblies other than Win32 Policy assemblies

    The first type of warning indicates that actions with the same name exist in multiple merge modules.  Windows Installer requires unique action names, and when attempting to merge MSMs that contain multiple actions with the same name, Windows Installer will exclude all but the first action.  In this case, the exact same SxsInstallCA and SxsUninstallCA actions exist in all of the VC 8.0 runtime MSMs, and so all but the first ones are excluded from the merging process.  However, all of these actions are identical and execute the same code behind the scenes, so it is safe to ignore this type of warning because you will not be losing any required functionality during the merge process.

    The second type of warning indicates that some identifiers are longer than the maximum values specified in the _Validation table of the MSI.  The documentation for ICE03 indicates that Windows Installer does not internally limit the column width to the specified value, so these warnings can be safely ignored.

    The third type of warning helps prevent authoring different components that install the same files to the same destination folder (which would violate Windows Installer component rules).  However, in the case of these VC 8.0 MSMs, the components have conditions that are mutually exclusive (Version9x and VersionNT < 501) so the component rules will not be violated and these warnings can be safely ignored.

    The fourth type of warning indicates that actions contain duplicate sequence numbers in the InstallExecuteSequence table.  When actions have duplicate sequence numbers, there is no guarantee about what order they will be run in.  However, in this case, the actions have no order dependencies and it is safe to ignore these warnings as well.

    The fifth type of warning helps prevent authoring incorrect keypath files for Win32 global assemblies that are installed to the WinSxS component store.  This warning indicates that they keypath should not be a manifest file unless the assembly is a Win32 policy assembly.  In this case, the assembly is a Win32 policy assembly, so these warnings can also be safely ignored.

    Note: it is possible to suppress the above warnings by configuring some settings in the WiX linker project property page in Visual Studio.  In general, however, I advise against doing that because if you enable suppressions, you might end up missing other warnings or errors in the same categories that are not safe to ignore.

    <update date="2/12/2008"> Added information about ICE03 warnings that can occur when merging the VC 8.0 MSMs that I missed when I originally wrote this post. </update>

    <update date="2/11/2009"> Removed references to policy MSMs because the general recommendation is to not include policy MSMs when redistributing the VC runtime files. </update>

     

  • Aaron Stebner's WebLog

    How to fix error installing .NET Framework 1.1 SP1 on a computer that has MS05-004 installed

    • 6 Comments

    I recently encountered a .NET Framework setup problem that is not described in my previously published .NET Framework hotfix/service pack troubleshooting guide while doing some testing for the upcoming version of Windows Media Center.  I installed a computer with Windows XP Media Center Edition 2005, the .NET Framework 1.1 and .NET Framework hotfix 886904 (MS05-004).  Then I went to Windows Update and found that it detected that I needed to install the .NET Framework 1.1 SP1 and it classified this as a high-priority update.  When I tried to install it from Windows Update, it failed for me with a generic "installation failed" error message.

    Of course, being the setup geek that I am, I wanted to figure out what was happening behind the scenes.  So I downloaded the setup package for the .NET Framework 1.1 SP1 from this location and ran it with full UI (instead of letting Windows Update run it for me in silent mode).  When I did this, I saw this error message:

    .NET Framework 1.1 SP1 error dialog

    This error message started me on the right track to find the solution to my problem.  I decided to check in Add or Remove Programs first to see if there were any hotfixes for .NET Framework 1.1 listed, and I found one named Microsoft .NET Framework 1.1 hotfix (KB886904).  Once I uninstalled that hotfix and rebooted, I was able to return to Windows Update and successfully install the .NET Framework 1.1 SP1.

    Ordinarily, .NET Framework service packs have logic built into their setup packages to automatically uninstall hotfixes and then apply the SP.  That was not possible in this scenario because the fix for MS05-004 was not included in .NET Framework 1.1 SP1.  The underlying security vulnerability was found after .NET 1.1 SP1 was tested and signed off on within Microsoft but before it went live on Windows Update.  Since .NET 1.1 SP1 did not have this fix, it did not have knowledge of the hotfix package for MS05-004 and was not able to automatically remove it.  That is also why you see a new version of MS05-004 offered on Windows Update immediately after you install .NET Framework 1.1 SP1 (this time it is named KB886903 instead of KB886904).  Future service packs for the .NET Framework 1.1 will have the fix for this issue included, so you will not see this error message if, for example, you try to install the .NET Framework 1.1 SP2 on a computer with 1.1 and KB886904 installed in the future when 1.1 SP2 is available.

    It is unfortunate that this type of setup scenario leads to a generic failure on Windows Update and does not help the average user find the solution to the problem.  I am not sure how many computers will have the exact combination of .NET 1.1 + MS05-004 installed before trying to install .NET 1.1 SP1, but hopefully if anyone does run into this they will be able to use the lesson I learned above to resolve the problem.

     

  • Aaron Stebner's WebLog

    Installing Microsoft Loopback Adapter

    • 17 Comments

    Hey all, one of the feedback forms from the hands-on lab I presented about remote debugging indicated that you'd like to hear more information about how to use the Microsoft Loopback Adapter that I used to mimic a LAN connection within the local machine to connect the development OS to the virtual machine.  Here are the steps I used to setup the loopback adapter.  I am going to see about creating a more formal tip article for this and post it somewhere on MSDN's embedded site also.  Please send me any feedback about whether or not this set of steps ends up working for you.....

    Installing Microsoft Loopback Adapter

    • Go to the Add Hardware control panel
    • Click Next on the first wizard screen
    • When asked if the hardware is connected, select Yes and click Next
    • In the list of installed hardware, scroll to the bottom and select Add a new hardware device and click Next
    • Choose the option titled Install the hardware that I manually select from a list (Advanced) and click Next
    • In the list of common hardware types, select Network adapters and click Next
    • In the list of manufacturers, select Microsoft.  Then in the list of network adapters, select Microsoft Loopback Adapter and click Next
    • Click Next one more time to install the Microsoft Loopback Adapter and then press Finish

    Now that you have installed the Microsoft Loopback Adapter, you need to configure an IP address for it.

    Configuring Microsoft Loopback Adapter

    • Go to the Network Connections control panel
    • Locate the LAN or High-Speed Internet connection that has a Device name of Microsoft Loopback Adapter, right-click on it and choose Properties
    • Select the Internet Protocol (TCP/IP) item and click Properties
    • Select the option to Use the following IP address and enter 192.168.2.1 for the IP address.  This will cause a subnet mask of 255.255.255.0 to appear
    • Click OK to accept the changes and Close to exit the Properties dialog

    Now you can disable your current LAN connection and enable your Microsoft Loopback Adapter connection by right-clicking on each connection in the Network Connections control panel and choosing Enable or Disable.

     

Page 5 of 48 (1,185 items) «34567»