Aaron Stebner's WebLog

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

August, 2005

  • Aaron Stebner's WebLog

    My adventure creating a Media Center add-in, part 2


    As you can probably tell by the timestamp from the previous entry in my running journal about learning how to create a Media Center add-in, I haven't had a ton of time in the past few weeks to devote to making forward progress on this project.  When I left off last time, I had gotten the Media Center SDK installed and was about to start exploring it.  There are a lot of different ways to go about learning new concepts, and the way I've found that I learn things most effectively is by getting hands-on.  I learn new coding concepts best by reverse engineering working real-world code, tweaking it to do new things, then using that knowledge as a basis to start writing something new.  So that is what I'm going to start out trying to do.

    I decided to start by exploring the contents of the SDK (installed by default to C:\Program Files\Microsoft\Microsoft Windows XP Media Center SDK).  I quickly notice Microsoft Windows XP Media Center SDK.chm in the root of this folder so I decide to browse through this first.  The high-level introduction to the SDK in the CHM file indicates that there are several options for developers who want to extend Media Center functionality.  It appears the major branching point for the type of development is to choose to write a Hosted HTML Application or an Add-In.  I'm not a huge fan of HTM/HTA/ActiveX development and I want to exercise some of my coding skills that I haven't gotten a chance to use in a few months, so I think the best choice for what I want to try to learn how to do first is going to be an add-in.

    I notice that there is a Sample Addins directory in the SDK folder, and there is a topic in the CHM that lists each of the sample add-ins and what concepts they demonstrate.  This looks like it will be really cool and useful for me because these are real-world applications and not simple "hello world" apps.  I think I'll start by picking apart these samples one after the other.  The Sample Addins directory has the source code and it also has Visual Studio .NET 2002 project files.  I only have VS 2003 installed, but that should theoretically be fine because it will prompt me to upgrade the project files when I try to open them.

    Since I'm really tired and have to get up early tomorrow I think I'm going to have to make this my stopping point for this time around.  Next time I'm going to look at the source code for the sample add-ins and see if I can get them building and plugged into my home Media Center machine to make sure I understand the end-to-end deployment scenario.

    Eventually I will have to decide what kind of add-in I want to write when I venture out on my own.  I've been trying to brainstorm a bit and read about what other folks are doing.  I found a couple of cool sounding projects in my reading so far:

    • From Charlie Owen's blog - an add-in to schedule TV recording via an RSS feed.  Since Charlie sits across the hall and a couple of doors down from me and I finally got a chance to meet him a few days ago, I should probably stop by and chat with him about this  :-)
    • On MSDN - an add-in to jump to specific times while playing back media.  The author of this one looks to have done a good job of describing the entire end-to-end development and deployment/testing process, and there is sample code here.  So this looks like a good place to go for more complex examples after I work through the simpler add-ins that are in the SDK.


  • Aaron Stebner's WebLog

    How to workaround errors installing .NET Framework 2.0 that are caused by registry permission problems


    I have had a few customers report problems installing the .NET Framework 2.0 with the following symptoms:

    • .NET Framework 2.0 setup fails and rolls back with no specific error message, just a generic "setup failed" message at the end
    • The action that fails is "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50215\regtlibv12.exe" "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50215\mscoree.tlb" or "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50215\regtlibv12.exe" "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50215\mscorlib.tlb" (you can find the error by using the steps described here)
    • The error code listed in the log file %temp%\dd_netfx20msi*.txt is 8002801c

    Examples of this problem are the comments located here and here, and the Product Feedback Center bugs located here and here and here.

    The underlying problem is that the Administrators group somehow was only granted read permission to some of the registry keys under HKEY_CLASSES_ROOT on these machines.  When the .NET Framework setup tries to register type libraries, it needs to create some new values under HKCR and it fails because of a lack of permissions (8002801c means "error accessing the OLE registry").  I have been able to confirm that this is the problem by having one of the customers use RegMon, but I haven't been able to figure out how the permissions got modified to be this way.  Up until now I also haven't been able to figure out how to fully reset the permissions so that .NET Framework setup will work.

    Fortunately one of the customers who had this problem contacted us with a solution that worked for them, and I wanted to list it here in case others run into this same problem in the future.  Here are the steps to follow to repair permissions to workaround this issue:

    1. Download the SubInACL tool from this Microsoft site and install it.  By default it will install to c:\Program Files\Windows Resource Kits\Tools
    2. Go to the Start menu, choose Run and type cmd
    3. Type cd /d %ProgramFiles%\Windows Resource Kits\Tools to change directories to the folder that SubInACL is installed to
    4. Type notepad reset.cmd and press yes to create a new file named reset.cmd in c:\Program Files\Windows Resource Kits\Tools
    5. Copy and paste the following contents into reset.cmd and then save and close it (or download it from here and rename it from reset.cmd.txt to reset.cmd):
      subinacl /subkeyreg HKEY_LOCAL_MACHINE /grant=administrators=f
      subinacl /subkeyreg HKEY_CURRENT_USER /grant=administrators=f
      subinacl /subkeyreg HKEY_CLASSES_ROOT /grant=administrators=f
      subinacl /subdirectories %SystemDrive% /grant=administrators=f
      subinacl /subkeyreg HKEY_LOCAL_MACHINE /grant=system=f
      subinacl /subkeyreg HKEY_CURRENT_USER /grant=system=f
      subinacl /subkeyreg HKEY_CLASSES_ROOT /grant=system=f
      subinacl /subdirectories %SystemDrive% /grant=system=f
    6. Type reset.cmd and press enter to run the SubInACL tool (you will need to have adminstrator privileges for this to run correctly).  This tool will take several minutes to run
    7. After reset.cmd completes, try to install the .NET Framework 2.0 or VS 2005 again

    Hopefully this will help.  If you try this and still have trouble getting setup to work correctly for the .NET Framework 2.0 or VS 2005, please contact me.


  • Aaron Stebner's WebLog

    A couple additional tips and tricks for authoring the MSI Media table for a setup


    Since I typed up my first list of tips and tricks for the Media table, volume labels, multi-disk MSI setups, etc last night, I thought of a few additional things that I forgot to mention or forgot the details of and needed to research a little bit more.  So here is a list of a little more random information about the Media table:

    1. When Windows Installer prompts the user to insert a disk, it uses the value in the DiskPrompt column of the Media table for the file that it is searching for.  This value can be translated into other languages to support non-English languages for your setup packages.  If desired, you can also use property values in the DiskPrompt column so that if you need to translate the same string multiple times, you can author all of your media table entries to refer to a single property value and then translate the property value once.
    2. If you have a multi-disk MSI setup that you want to ship on a DVD instead of on multiple CDs, you cannot simply copy the contents of each CD to a folder and burn a DVD.  You will have to modify the Media table of your MSI prior to burning it to DVD.  Each VolumeLabel entry that previously existed to support CD layouts needs to be changed to be either blank or the same value as you intend to use for the volume label for the DVD that you burn.  For example, in Visual Studio, we shipped the Enterprise Architect CDs with volume labels VSENARD1 and VSENARD2, and then updated the MSI for the DVD so that the volume label was VSENARD1 for all of the files.
    3. If you want to figure out what disk you should expect any given file to appear on when you burn media for your product, you can look up the file in the File table, take not of the value in the Sequence column, and then cross-reference the LastSequence column of the Media table.
    4. There is a bug where if you install a multi-disk setup on a computer that has multiple CD/DVD drives and insert one of the disks in one drive and another disk in one of the other drives, you will not be prompted to swap disks when setup needs to install files located on disk 2.  Instead of a standard disk swap dialog, you will see a 1308 "file not found" error in this scenario.  Putting the next disk into th same drive as disk 1 and pressing retry will allow setup to complete.  We ended up seeing several reports of this when working on VS 2003 because it shipped on 2 disks and some customers thought they could insert both disks simultaneously and have setup complete without any further intervention.


  • Aaron Stebner's WebLog

    Tips and tricks for authoring the MSI Media table for a setup


    Since Visual Studio is one of the few multi-disk MSI packages that I am aware of, our team has had more experience using the Media table and run into more problems while trying to release builds on CD and DVD than any other team I know of within Microsoft.  The Media table is documented in the Windows Installer MSDN documentation (this is a good starting point).  Here is a list of some random information (and a couple of bugs in our products) that we discovered about the Media table during the process of shipping VS .NET 2002 and 2003 and the .NET Framework 1.0 and 1.1:

    1. The value listed in the VolumeLabel column of the table much match the volume label of the physical disk being installed from if the product is being installed from a removable media drive.  If the physical disk has a different volume label than what is listed in the Media table for the file that the MSI is attempting to install, you will get a dialog asking you to swap disks.
    2. The documentation shows that you can leave the VolumeLabel column blank, but if you do this, make sure that your entire setup package fits on a single disk or else your users will not receive proper disk swap notifications and the installation will fail because Windows Installer won't be able to find files it needs to install.
    3. Windows Installer treats local CD and DVD drives as removable media, and uses the values in the VolumeLabel column of the Media table if installation happens from one of those locations.
    4. Windows Installer does not treat a shared network drive that maps to a CD/DVD drive as a removable drive, and if you install from such a shared drive you will receive a 1308 (file not found) error for the first file that is expected to appear on disk 2.  When that happens you will have to swap disks on the machine that has its CD/DVD drive shared out and then press retry on the 1308 error dialog on the machine you are installing on.
    5. If you provide a volume label for one of the entries in the Media table of an MSI and there are multiple entries, then MSI will check the volume label to make sure it matches even for an installation that does not span multiple disks.  We ran into this for the .NET Framework - the product is small enough to fit on a single disk, but we had several embedded CAB files (which each require their own Media table entry) and a set of files in an external cab that we listed with the volume label URTSTDD1.  When installing from the self-extracting dotnetfx.exe package, setup always copies itself to the local hard drive (in a folder under %temp%) so MSI never considered that to be a removable media installation.  When one of our partners tried to extract the contents of dotnetfx.exe and ship this on their installation media and install by calling netfx.msi directly, they started getting prompted to swap disks.  We have fixed this in the .NET Framework 2.0 by calculating in our build process that the .NET Framework is less than the size of a burned CD and leaving the VolumeLabel columns in the Media table blank for all entries.
    6. Windows Installer does not support CD/DVD jukebox installation scenarios.  Once you start installing from a specific CD/DVD drive letter, you will have to swap disks on that drive to complete installation even if you have other CD/DVD drives on your machine.


  • Aaron Stebner's WebLog

    Automating performance optimizations for Windows Media Center


    I recently stumbled across a KB article that lists some performance optimization tips and tricks for Windows Media Center and I also saw some of the steps that we recommend to folks inside of Microsoft, which are roughly the same as the KB article.  What seems to be missing from all of these performance recommendations is steps for how to automate these steps.  Here are ways to run some of the key Media Center performance optimization steps automatically so that it can be scripted and run as a scheduled task if desired.

    Run Disk Defragmentation

    • %windir%\system32\defrag.exe <drive letter>

    Run Disk Cleanup

    • %windir%\system32\cleanmgr.exe /d <drive letter>

    More info about command line options for disk cleanup can be found in this KB article

    Remove Temporary Files

    • rd /s /q *.tmp

    Remove Memory Dump Files

    • rd /s /q *.dmp

    Disable System Restore

    System restore monitors system changes and saves the system state as a restore point.  These restore points are created when any hotfix is installed and in other scenarios, and the files they use to store system state cannot be defragmented using the utility listed above.  Therefore, you may want to disable system restore by setting the following registry keys/values:

    Registry Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore
    Registry Value: DisableSR
    Data Type: REG_DWORD
    Value Data: 1

    Registry Key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sr
    Registry Value: Start
    Data Type: REG_DWORD
    Value Data: 4

    Disable Disk Indexing

    Disabling disk indexing is one of the optimization steps not listed in the current KB article for Media Center performance.  However, I have not been able to find a way to disable disk indexing automatically, but it can be done with these steps.  If anyone reading this knows how to automate disabling disk indexing, please post a comment!

    1. Navigate to My Computer 
    2. Right click on each drive letter and choose Properties 
    3. Uncheck the item labeled Allow Indexing Service to index this disk for fast file searching and click OK 
    4. Choose the radio button labeled Apply changes to <drive letter>, folders and files and click OK


  • Aaron Stebner's WebLog

    Interesting bug in the LaunchCondition table for .NET Framework 2.0 64-bit setup


    I was looking at the setup package for the x64 version of the .NET Framework beta 2 recently.  I needed to try to install it on a Windows Vista machine in order to work on an issue related to Media Center, and I got an interesting error telling me "Microsoft .NET Framework 2.0 (x64) is not supported on Windows 95, Windows NT, Windows 2000 without Service Pack 3 or greater, and Windows Server 2003 without Service Pack 1 or greater."  Granted, it isn't really a valid scenario to try to install the MSI-based .NET Framework 2.0 package on Vista because the .NET Framework 2.0 is already part of the OS, but since I got this error message that blocked me but listed a completely wrong set of OS's, I had to dig a little deeper at least to satisfy my own curiosity.

    While I was looking at the MSI, I came across this condition in the LaunchCondition table:

    (Version9X >= 410) OR ((VersionNT = 500) AND (ServicePackLevel >= 3)) OR (VersionNT = 501) OR ((VersionNT = 502) AND (ServicePackLevel >= 1))

    I stared at this set of conditions for a while because something just felt wrong about it.  Then it came to me - this launch condition is listing the OS's that the MSI will allow the .NET Framework 2.0 x64 version to install on.  Notice that the supported versions stop with VersionNT = 502.  Since the VersionNT value 502 is equivalent to Windows Server 2003, it would block installation on any OS with a version number higher than Windows Server 2003.  That is fine for Vista because .NET 2.0 will already be a part of the OS, but that is not fine for future versions of Windows after Vista.

    To make a long story short, I reported a bug on this issue and they're considering a fix for it for the final version of .NET Framework 2.0 x64 and ia64 editions.  However, I thought it illustrated a couple of more important points to keep in mind when designing an MSI-based setup:

    1. Be careful with using LaunchConditions.  The logic can be confusing and convoluted and getting them wrong will block your setup from being allowed to run, which is fairly painful to try to patch or recover from.  We put a launch condition in for the .NET Framework 1.1 to block installation on 64-bit platforms but then after 1.1 shipped Microsoft started releasing 64-bit OS's, and the application compatibility team had to add a shim to the OS to override this launch condition that was no longer valid.
    2. Try to keep the future in mind when designing your setup whenever possible.  In my experience, this is really hard to do but very important.  For example, do not limit your setup authoring to only account for operating systems that are available when your product ships.  Think about making your version detection generic unless there is some specific reason you would not want your users to install your product on some future OS.  Also, think about whether you will be releasing future versions of the product and whether or not you want to have both versions co-exist on the same machine - and if so, learn and know the MSI component rules and apply them to the design of all versions of your product.  We did not get things exactly right for the .NET Framework 1.0 and that is why you will see files named sbs*.dll installed to %windir%\Microsoft.NET\Framework with all versions 1.1 and higher - these files bail us out in uninstall scenarios by adding extra component ref-counts to some resources that would otherwise be uninstalled incorrectly.


  • Aaron Stebner's WebLog

    Possible bug installing VS 2005 beta 2 on Windows Vista (Longhorn) beta 1


    We have seen a few reports inside of Microsoft of problems installing VS 2005 beta 2 on Windows Vista (previously codenamed Longhorn) beta 1 now that Vista beta 1 has been released and teams are using it more widely.  In addition we have seen at least one report on the product feedback site from an external customer (the bug report located here).

    This bug does not reproduce 100% of the time and is related to a performance issue or possibly a race condition in the file system code somewhere (the bug is still under investigation and a cause has not yet been fully identified).  The symptoms seen during VS 2005 setup will be that MSXML6 fails to install and setup stops there, or that some of the components installed after VS 2005 beta 2 (specifically the 2 versions of the .NET Compact Framework and SQL Mobile) report that they failed to install.

    The workaround to resolve this bug if you run into it is to to the following:

    1. Navigate to the WCU subfolder on the VS 2005 beta 2 DVD
    2. Go to the each of the MSXML, NetCF and SQLCE folders
    3. Install the MSI packages in each of those folders by right-clicking on them and choosing Install
    4. After these complete, re-run VS 2005 beta 2 setup and it should complete with no further problems on Windows Vista beta 1.

    Also, as a side note, I wanted to mention that Windows Vista beta 1 includes the equivalent of the .NET Framework 2.0 beta 2 bits (with a few additional post-beta 2 bug fixes).  Since the beta 2 bits are installed as part of the OS, you cannot replace them with later builds of the .NET Framework 2.0.  Therefore, you will be able to install the beta 2 versions of VS 2005 on Vista beta 1.


  • Aaron Stebner's WebLog

    How does Windows Update decide whether or not to offer .NET Framework 1.1 and SP1?


    I have seen a few issues in the past where a user visits Windows Update and is not offered the .NET Framework 1.1 for download even if it is not installed on the computer, or conversely the computer is offered the .NET Framework 1.1 even if it is already installed.

    Windows Update has the ability to use a variety of detection methods to determine whether or not to offer a package for download, including checking for the existence of a registry key/value, checking the version stored in a registry value or the version of specified files on the system, and so on.  Windows Update also checks for 2 types of conditions - Is Installable (the conditions that must be true in order to offer the package) and Is Installed (the conditions that will prevent the package from being offered if they are true).  There is not any enforcement in the tool that we use internally that the Is Installable and Is Installed conditions be exact inverses, so there are cases where they could both end up true or false, which can cause incorrect offering behaviors.

    Here are the conditions that are currently being used to control the offering of the .NET Framework 1.1 and 1.1 SP1:

    On Windows 98, Windows ME, NT 4, Windows 2000 and Windows XP,

    The .NET Framework 1.1 will be offered on Windows Update if the registry key named HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components\{CB2F7EDD-9D1F-43C1-90FC-4F52EAE172A1} does not exist.  The .NET Framework 1.1 SP1 will be offered if HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components\{CB2F7EDD-9D1F-43C1-90FC-4F52EAE172A1} exists and HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components\{411EDCF7-755D-414E-A74B-3DCD6583F589} does not exist.

    On Windows Server 2003

    The .NET Framework 1.1 is installed as part of the OS, so it will never be offered on Windows Update.  The .NET Framework 1.1 SP1 will be offered if HKEY_LOCAL_MACHINE\Software\Microsoft\Updates\.NETFramework\1.1\KB867460 does not exist.

    Also note that as I described here, the .NET Framework 1.1 is separated into a core package and satellite language packs for non-English languages.  If you visit Windows Update on a non-English computer and choose to install the .NET Framework 1.1, Windows Update will automatically install the .NET Framework 1.1 and the language pack that matches the language of the OS on your computer.  They will be chained together and appear to install as a single unit in the Windows Update UI, although they will actually be separate MSI packages and have separate Add/Remove Programs entries.


  • Aaron Stebner's WebLog

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


    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

    How to locate the cause of error code 1603 in a verbose MSI log file


    There is a trick I use very often when trying to figure out why an MSI-based setup is failing that I wanted to share with everyone.  I believe it is commonly known among setup developers and people who have to troubleshoot failed setups, but I could not find any "official" documentation for it.  This trick helps narrow down the root cause of error code 1603, which is a generic catch-all error code that means "fatal error during installation".  The 1603 error code is returned when any action fails during an installation, and most commonly it indicates that one of the custom actions in the MSI failed.

    When I encounter a failed setup with return code 1603, here are the steps that I follow:

    1. Re-run the setup with verbose logging enabled using steps similar to those that I listed here (if there is not already a verbose log file available).  Those steps will generate a verbose log file named msi*.log in the %temp% directory the next time the setup package is executed.

      Important note - some MSI-based setups, including the .NET Framework 2.0, 3.0, 3.5 and higher and Visual Studio, will not create log files named %temp%\msi*.log even if using the instructions listed below.  Please see this blog post for more details about why that is the case and also for a list of some products that I know of that use different log file creation logic and the locations of the log files that they create.

    2. Open the verbose log in a text editor such as notepad and search for the string "return value 3".  In nearly all cases, this takes me to the section in the verbose log that lists the action that failed that initially caused setup to rollback.
    3. Review the contents of the log file immediately above the "return value 3" string to determine which custom action or standard action failed.
    4. Depending on which action is failing, I will proceed to more detailed debugging from here

    I find that the biggest hurdle to debugging a failed setup is often zeroing in on which part of the setup is actually failing, and this trick of searching for "return value 3" ends up helping speed this process up in nearly all cases.  Of course, it does not work in 100% of scenarios.  Notably, if you are running setup on a non-English version of Windows, the string "return value 3" is written to the log file in the language of the operating system instead of in English, so string searches will not work.

    Also note that there is an MSI verbose log parsing tool in the Windows Installer PSDK that is also very useful in locating errors inside verbose log files.  You can read more about this parsing tool (called wilogutl.exe) by clicking here.  This tool is more thorough in identifying errors, but most often I end up not using it because it is faster to open the log in notepad and do a string search than it is to load up the parsing tool, browse to the log file, wait for it to parse the whole log and then read the output it produces.

    <update date="1/21/2009"> Added a caveat to these instructions indicating that some setups create their own verbose logs and enabling verbose logging using the Windows Installer logging registry keys will not work as expected for those setups. </update>


Page 2 of 2 (35 items) 12