Aaron Stebner's WebLog

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

June, 2005

  • Aaron Stebner's WebLog

    A couple of new Visual Studio and .NET Framework setup blogs


    A couple of colleagues of mine from my days on the Visual Studio and .NET Framework setup team have started blogging and I wanted to post links to their blogs here and encourage everyone to check them out.  Quan has already posted some nice workarounds to tricky setup issues seen in the VS 2005 beta 2 and June 2005 CTP timeframes.  Pete started working on the setup team at the same time I did back in the day, and we can swap stories about the old days of VS .NET 2002, .NET Framework 1.0, and all the growing pains we went through to get those products shipped  :-)

    You can check out their blogs at the following links:


  • Aaron Stebner's WebLog

    Installing an assembly to the GAC and the local file system


    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

    How to repair the .NET Framework 1.1 that ships as part of the OS on Windows Server 2003


    The .NET Framework 1.1 ships as an OS component on the 32-bit Windows Server 2003 family of operating systems.  This .NET Framework component is a hidden, always-installed component with the exception of ASP.NET (which can be found as a selectable item underneath the Application Server item in the Add/Remove Windows Components control panel applet).

    I have seen cases where the .NET Framework 1.1 stops working correctly on Windows Server 2003 (often due to bugs in daily builds of the .NET Framework 2.0).  In those cases, it is useful to perform a repair to get the .NET Framework 1.1 back to a known good state.  However, it can be difficult to figure out how to repair .NET 1.1 in these scenarios because the component is hidden and because there is some specific logic in the setup DLL that installs this component that prevents uninstall and reinstall after OS setup has completed.

    In general, you can repair the .NET Framework 1.1 that ships with Windows Server 2003 by re-running OS setup and choosing to repair/reinstall, which will trigger the .NET Framework 1.1 component setup to rerun.

    In addition, the following steps can be performed in order to repair the .NET Framework 1.1 on Windows Server 2003 while also avoiding the need to run a full OS reinstall:

    1. Delete the registry value netfx under HKLM\Software\Microsoft\Windows\CurrentVersion\Setup\OC Manager\Subcomponents
    2. Create a file named netfx_repair.inf that contains the following text (or download it from here):

      Signature = "$Windows NT$"

    3. Open a cmd prompt and run the following command: sysocmgr /i:<full path to netfx_repair.inf>.

      This will bring up the Windows optional component installer wizard.  Press next and installation/repair of the .NET Framework 1.1 component will begin.  You will be asked for a path to install the files from if the location listed in the SourcePath value under HKLM\Software\Microsoft\Windows\CurrentVersion\Setup is not accessible or no longer contains the necessary OS source files.  If this happens, you will need to point the wizard to the i386 directory of the OS source disk or a network share that contains the files.  Keep in mind that if you have a version of Windows Server 2003 with a service pack integrated into it, you will need to use a source location that also includes the service pack.

    4. After the wizard completes installation, you will have to manually rerun a modified command line to install assemblies to the GAC because the command line used by the .NET Framework 1.1 component only works correctly when OS installation is in progress.  The command line is the following:

      "%windir%\Microsoft.NET\Framework\v1.1.4322\gacutil.exe" /f /il %windir%\Microsoft.NET\Framework\v1.1.4322\assemblylist.txt

      You should substitute %windir% with the actual Windows directory on your system.

    <update date="11/1/2005"> There is a Knowledge Base article that also describes how to troubleshoot .NET Framework 1.1 installation issues on Windows Server 2003 that can be useful in this type of scenarios.  You can find it at this location. </update>

    <update date="9/29/2008"> Added a note about using source files with integrated service packs if the OS was originally installed with a service pack integrated. </update>


  • Aaron Stebner's WebLog

    Using MsiBreak to gather debugging information for .NET Framework setup failures


    I have been working on the .NET Framework setup since before v1.0 shipped, and in that time I've seen all sorts of bugs and setup failures.  There is one particularly tricky set of bugs that all show the same symptom but that we haven't been able to track down a common root cause for.  The error that is seen during setup is a failure to register System.EnterpriseServices.dll or a problem running RegSvcs.exe /bootstrapi, which then causes setup to stop and rollback.

    Almost none of the cases I have seen where this error appears were actually caused by the file System.EnterpriseServices.dll itself.  It is a bit misleading because the registration of this file is done by a custom action during setup, and that custom action is the first time that the version of the CLR we are trying to install is used to run managed code on the computer.  So that means that if anything is wrong on the machine to cause that version of the CLR to not work properly, the error the user sees is that this DLL failed to register.

    When we encounter an error like this, we typically try the following cleanup and troubleshooting steps in the order listed below.

    1. Download the .NET Framework 1.0 and 1.1 cleanup tool and run it
    2. Verify that the data in the Locale registry value located at HKEY_USERS\.Default\Control Panel\International is valid.  The Locale value should contain one of the values listed at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Nls\LocaleMapIDs
    3. Get a crash dump with Windbg on the custom action that registers System.EnterpriseServices.dll

    In many cases, running the cleanup tool is sufficient, but every once in a while we run into a computer in a state that we can't diagnose and we have to try some more advanced debugging techniques like those listed in steps 2 and 3.

    We use the following steps to configure the MsiBreak environment variable to cause .NET Framework setup to pause at the beginning of the custom action that registers System.EnterpriseServices.dll, attach a debugger and gather crash dump information:

    1. Download and install the Debugging Tools for Windows
    2. Right-click My Computer, and then click Properties.
    3. On the Advanced tab, click Environment Variables, and then under System Variables, click New.
      Note: You must add MsiBreak to the list of System Variables (and not to the list of User Variables).
    4. In the Variable Name field, enter "MsiBreak" (without the quotation marks).
    5. In the Variable Value field, enter the name of custom action you want to break on.  The name must match the name listed in the Action column of the CustomAction table of the MSI:
      For .NET Framework 1.0 or 1.1 setup: CA_ComregEnterpriseServices.3643236F_FC70_11D3_A536_0090278A1BB8
      For .NET Framework 2.0 setup: DD_CA_ComregEnterpriseServices_X86.3643236F_FC70_11D3_A536_0090278A1BB8
    6. Run .NET Framework setup and start installing
    7. During installation, a break message will appear stating "To debug your custom action, attach your debugger to process XXX (0xZZZ) and press OK".  Open WinDBG instead of following the instructions on the dialog that pops up.  If you are running on Windows Vista, you will need to launch WinDBG with elevated privileges.  To do that, right-click on WinDBG.exe and choose Run as administrator.
    8. From the File menu, choose Open Executable...
    9. In the File name text box, enter the following information:
      For .NET Framework 1.0 setup: %windir%\Microsoft.NET\Framework\v1.0.3705\regasm.exe
      For .NET Framework 1.1 setup: %windir%\Microsoft.NET\Framework\v1.1.4322\regsvcs.exe
      For .NET Framework 2.0 setup: %windir%\Microsoft.NET\Framework\v2.0.50215\regsvcs.exe (or change the build number depending on what build of .NET Framework 2.0 is being installed)
    10. In the Arguments text box, enter the following information:
      For .NET Framework 1.0 setup: %windir%\Microsoft.NET\Framework\v1.0.3705\System.EnterpriseServices.dll
      For .NET Framework 1.1 or 2.0 setup: /bootstrapi
    11. After entering the above information, choose Yes to save base workspace information
    12. Press g in the Windbg window to resume execution until the process crashes, then save the crash log to a file

    Variations of the above steps can also be used to gather debugging information for any custom action that fails during an MSI-based setup as long as you are able to consistently reproduce the crash during setup.  You just need to substitute the appropriate custom action name in step 5 (by looking at the verbose MSI log file or looking at the MSI in Orca to get the exact name).  You also need to substitute the custom action name and command line parameters in steps 9 and 10 above.  In the case of this example, the custom actions are executable files that are installed as a part of .NET Framework setup.  If the custom action is a file streamed into the binary table of the MSI, I believe you will need to extract the file from the MSI and run it using rundll32.exe or something like that (but I haven't yet tried to do that to verify that it works like I think it will).

    <update date="9/25/2006"> Added a note about running WinDBG with elevated privileges on Windows Vista </update>


  • Aaron Stebner's WebLog

    VS 2005 beta 2 setup fails with 1935 or 2908 assembly installation error


    I have heard from a few people (including this customer comment on a previous blog post and a fellow Microsoft employee) who have tried to install VS 2005 beta 2 and received 1935 (or 2908) assembly install errors with HRESULT value 0x8002802F.  If you take a look at my 1935 troubleshooting guide, you will see that this error means "function not defined in specified DLL."  When this error occurs during .NET Framework or VS setup, it generally means that the version of mscoree.dll located in %windir%\system32 on the computer does not match the version needed by Windows Installer to call specific Fusion APIs to install assemblies to the GAC.

    In the case of the Microsoft employee who contacted me, VS setup detected that the .NET Framework 2.0 was already installed and skipped that prerequisite step.  However, the machine actually only had .NET Framework 1.1 installed, and the version of %windir%\system32\mscoree.dll was 1.1.4322.573.  When VS setup tried to install assemblies to the GAC, it failed because Windows Installer tried to call into a 2.0-specific API from mscoree.dll (needed because there are new processor architecture attributes on VS 2005 assemblies that only 2.0 knows about).  Since the version of mscoree.dll on the system was 1.1, these API calls failed.

    I found that this computer had the following orphaned registry key/value that VS setup found and used to determine that .NET Framework 2.0 beta 2 was already installed:

    • Key name: HKLM\Software\Microsoft\NET Framework Setup\NDP\v2.0.50215
    • Value name: MSI
    • Data type: REG_DWORD
    • Value data: 1

    On this employee's machine, once I deleted this key/value and re-ran VS 2005 beta 2 setup, it detected that it needed to install the .NET Framework 2.0 beta 2.  Once that completed, VS setup worked perfectly.

    As a side note if you're really interested, you could use some of the setup reverse engineering tricks that I describe here to determine the exact location of this registry key.  In this case, the key/value are listed in the [gencomp18] section of the file named baseline.dat in the setup subdirectory of the VS 2005 beta 2 DVD.


  • Aaron Stebner's WebLog

    Cool tip if you are seeing performance problems in Visual Studio 2005 Team System projects


    I found this blog post that I wanted to link to here as well.  Yosi provides a good set of troubleshooting steps and a workaround if you are seeing performance problems creating team projects using Visual Studio 2005 Team System.  In a nutshell - you can configure Internet Explorer to not use your proxy server and significantly improve the startup time when creating new team projects in multi-server scenarios.


  • Aaron Stebner's WebLog

    Visual Studio 2005 beta 2 will not install on Windows XP Professional x64 Edition


    If anyone has tried to install Visual Studio 2005 beta 2 on Windows XP Professional x64 Edition, I am sure you have noticed that installation does not work correctly because VS setup says that you need to install Windows XP Service Pack 2 even though there is not an SP2 available for Windows XP Professional x64 Edition.  This is a bug in setup for Visual Studio 2005 beta 2 that has been fixed in later builds.

    In the meantime, you can workaround this issue by doing one of the following:

    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 beta 2
    5. Rerun regedit.exe and change the CSDVersion value back to what it was originally


    1. Copy the contents of the Visual Studio 2005 beta 2 DVD to a local folder
    2. Go to the Setup subdirectory and open the file baseline.dat in a text editor such as notepad.exe
    3. Locate the section named [gencomp6] - this is the section that tells VS setup to block if Windows XP SP2 is not installed
    4. Change the InstallOnAMD64 and InstallOnIA64 values from 1 to 0
    5. Save and close baseline.dat
    6. Run setup.exe from the local folder that you copied the contents of the DVD to in step 1 and install Visual Studio 2005 beta 2


  • Aaron Stebner's WebLog

    How to get around the MSI 3.0 block in .NET Framework 2.0 Beta 2 setup


    <updated on June 6, 2005 - reworded one of the caveats and moved it to be caveat #1 based on the comment from HeathS about the requirement that Windows Installer 3.x be present in order to install .NET Framework 2.0 hotfixes or service packs>

    Some of you may have noticed that .NET Framework 2.0 beta 2 requires a minimum version of Windows Installer 3.0 and if it is not installed on the computer, you will have to download it and install it as a separate step.  This is a change from .NET Framework 2.0 beta 1, which required a minimum version of Windows Installer 2.0 and carried the installation packages for Windows Installer 2.0 as part of the dotnetfx.exe package.

    The increased minimum requirement from Windows Installer 2.0 to Windows Installer 3.0 (and possibly to 3.1 by the time .NET Framework 2.0 ships) is due to a lot of servicing/patching fixes available in Windows Installer 3.x.  Since there aren't any strict setup-time requirements for Windows Installer 3.0 in the .NET Framework setup, you can use some unsupported reverse engineering tricks to make .NET Framework 2.0 beta 2 setup work if you only have Windows Installer 2.0 installed.

    Before I list the steps I want to list a couple of important caveats:

    1. You will not be able to install any hotfixes or service packs for .NET Framework 2.0 if you use this method and install with only Windows Installer 2.0 present on your machine.  Therefor, this should only be used for testing purposes in case you have some dire need to unblock a single machine from getting the .NET Framework 2.0 installed that you plan to reimage after you are done testing.  In production scenarios, you really should install Windows Installer 3.1 because of the greatly improved product patching that it supports (described as part of this article).
    2. The .NET Framework 2.0 setup does have a technical requirement that the computer have at least Windows Installer 2.0, so please don't try to use this technique to unblock installation on a machine with Windows Installer 1.x installed

    With that out of the way, here are the steps you can use to get .NET Framework 2.0 beta 2 to install on a machine with only Windows Installer 2.0 present:

    1. Download the .NET Framework 2.0 beta 2 setup and save the file dotnetfx.exe to your local hard drive
    2. Open a cmd prompt and run the following command to extract the contents of dotnetfx.exe: dotnetfx.exe /t:"c:\temp" /c (or you can substitute any folder name for "c:\temp" in this command line)
    3. Go to the folder c:\temp and open the file install.ini in a text editor such as notepad.exe
    4. Find the [DetectDarwin] section in install.ini.  This section controls which version of Windows Installer setup will look for.  You can modify the value from the default 3.0 to 2.0 for each of the processor types (x86, i64 and a64)
    5. Save and close install.ini
    6. Run install.exe from the folder c:\temp to start .NET Framework setup

    Note that if you want to use these steps for one of the 64-bit versions of .NET Framework 2.0, you should substitute "netfx64.exe" for every instance of "dotnetfx.exe" above.


  • Aaron Stebner's WebLog

    Always Ready for Windows Media Center


    I found an article in PCWorld this week that talks about a new Windows Media Center computer being produced by Shuttle with Always Ready technology.  Always Ready is sort of a sub-sleep state that allows Media Center to go into a deep hibernation, which is useful to conserve energy and reduce noise.  But the machine remains available to do things like record TV programs, and it is able to start back up from the sub-sleep state very quickly.  For example, the Shuttle machine in the article could start up in less than 5 seconds.

    There is also a slide deck from WinHec 2004 that introduces and explains Always Ready from a theoretical standpoint that I found pretty interesting.


  • Aaron Stebner's WebLog

    How to fix problem installing SQL Express if SQL Server 2005 is already installed


    <updated on June 3, 2005 - changed the product name from "SQL Server Tools Express" to "Microsoft SQL Server 2005 Tools Express Edition CTP" based on the full official name as it appears in Add/Remove Programs>

    There is a known setup interaction issue with beta versions of SQL Server 2005 (codename Yukon).  There is a conflict between the SQL Tools that are installed with SQL Express 2005 Beta and the SQL Tools that are installed with the full SQL Server 2005 Beta.  If SQL Server 2005 Beta with SQL Tools is installed then SQL Express will fail, and vice versa. 

    You can workaround this issue by doing one of the following:

    Scenario 1 - Install SQL Express first

    1. Install SQL Express (as a standalone product or as a part of VS 2005 beta setup)
    2. Go to Add/Remove Programs and remove the product named Microsoft SQL Server 2005 Tools Express Edition CTP
    3. Install SQL Server 2005 Beta with SQL Tools

    Scenario 2 - Install SQL Server 2005 Beta first

    1. Install SQL Server 2005 Beta without SQL Tools
    2. Install SQL Express (as a standalone product or as a part of VS 2005 beta setup)
    3. Go to Add/Remove Programs and remove the product named Microsoft SQL Server 2005 Tools Express Edition CTP
    4. Re-run SQL Server 2005 Beta setup and select SQL Tools

    This workaround should work for the version of SQL Express that is included with VS 2005 beta 1 and VS 2005 beta 2.  This scenario is a known issue that the SQL team is planning to address before SQL Server 2005 releases.


Page 1 of 1 (10 items)