Aaron Stebner's WebLog

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

December, 2008

  • Aaron Stebner's WebLog

    Links to information about .NET Framework package sizes and web-based detection logic

    • 0 Comments

    Back when the .NET Framework 3.5 shipped, I posted a brief explanation about the size and contents of the .NET Framework 3.5 full installation package.

    Recently, Scott Hanselman created a site called SmallestDotNet.com that includes script-based logic to detect the latest version of the .NET Framework that is installed on your system and list the minimal components that need to be installed in order to upgrade the system to the .NET Framework 3.5 SP1.  This site also contains the code for a script block that you can copy and paste into your own web page if you want to use it for your deployment scenarios.

    This type of detection logic can be useful for web-based installers for applications that require the .NET Framework 3.5, and in some scenarios it can be a useful alternative to the sample detection code that I posted on my blog (which is written in C++ and is intended for use by rich-client installers that users download and run on their systems).

    Scott also describes the behind-the-scenes logic used by the SmallestDotNet.com site in a blog post at http://www.hanselman.com/blog/SmallestDotNetOnTheSizeOfTheNETFramework.aspx.  In that blog post, he also describes more detail about the online and offline installers for various versions of the .NET Framework and options for minimizing download size in online install scenarios.

  • Aaron Stebner's WebLog

    How to implement, build and test a Windows Installer major upgrade in WiX v3.0

    • 9 Comments

    When I create an MSI-based installer, one of the things I typically include in the setup authoring is some logic to allow me to implement Windows Installer major upgrades if/when I need to release a new version of the MSI in the future.  I typically include this authoring even if I don't currently plan to release a future version that I would need to use it for.  Doing so gives me flexibility if/when I decide to update the MSI in the future.

    There are some specific things you need to include in your MSI to enable major upgrades, and as I've learned about how to do this, I've found that the information is scattered around in several different places (MSDN, WiX documentation, blog posts, etc).  As a result, I decided to create a couple of simple samples that I copy and paste from each time I create new MSI-based installers using WiX v3.0.

    This blog post will use the samples that I created and posted at http://cid-27e6a35d1a492af7.skydrive.live.com/self.aspx/Blog%7C_Tools/WiX%20Samples/wix%7C_sample%7C_major%7C_upgrade.zip to demonstrate how to implement Windows Installer major upgrade functionality in an MSI created with WiX v3.0.

    Step 1: Add upgrade information needed to cause new versions to upgrade older versions

    In order to allow major upgrades, an MSI must include the following information:

    • An UpgradeCode property in the Property table.  In WiX v3.0, this means you must include an UpgradeCode attribute in your Product element.  From the example, this looks like the following:

      <Product Id="$(var.Property_ProductCode)" UpgradeCode="!(loc.Property_UpgradeCode)" Name="!(loc.Property_ProductName)" Language="!(loc.Property_ProductLanguage)" Version="$(var.ProductVersion)" Manufacturer="!(loc.Property_CompanyName)">

    • An entry in the Upgrade table that defines the range of previous versions that should be upgraded by the new MSI.  Typically, I use a range from version 1.0.0 up to the current MSI's version, not including the current version.  From the example, this looks like the following:

      <Upgrade Id="!(loc.Property_UpgradeCode)">
        <UpgradeVersion Minimum="1.0.0" IncludeMinimum="yes" Maximum="$(var.ProductVersion)" IncludeMaximum="no" Property="OLDERVERSIONBEINGUPGRADED" />
      </Upgrade>

      The exact name of the property specified in the UpgradeVersion element does not matter, but it must be in all capital letters to indicate to Windows Installer that it is a public property.

    • An entry in the InstallExecuteSequence table that schedules the RemoveExistingProducts action.  There are several options for where you can schedule RemoveExistingProducts in your product’s sequence table, and you will need to review the options and choose the one that makes the most sense for your scenarios.  You can find a summary of the options at http://msdn.microsoft.com/library/aa371197.aspx.  In my example, I chose to schedule it after InstallInitialize, and that looks like the following:

      <InstallExecuteSequence>
        <RemoveExistingProducts After="InstallInitialize" />
      </InstallExecuteSequence>

    Note - Windows Installer looks for other installed MSIs with the same UpgradeCode value during the FindRelatedProducts action.  If you don't specifically schedule the FindRelatedProducts action in your setup authoring, WiX will automatically schedule it for you when it creates your MSI.  I did not schedule FindRelatedProducts in the sample I created for this reason.

    Step 2: Add logic to handle out-of-order installations (installing version 2 then trying to install version 1)

    The information provided in step 1 will allow your MSI to uninstall older versions of your MSI during the install process for newer versions.  In order to be complete, you should also include information in your MSI to handle scenarios where a user attempts to install a newer version of your MSI and then install an older version afterwards (an out-of-order installation).  This step is not strictly necessary, but including this information in your MSI allows you to provide a more user-friendly experience in the case of an out-of-order installation scenario.

    Detecting an out-of-order installation requires authoring another entry in the Upgrade table that defines a property that will be set if a newer version of the MSI is found on the user's system.  From the example, this looks like the following:

    <Upgrade Id="!(loc.Property_UpgradeCode)">
      <UpgradeVersion Minimum="$(var.ProductVersion)" OnlyDetect="yes" Property="NEWERVERSIONDETECTED" />
    </Upgrade>

    Once you have defined the detection property, you need to decide how you want your MSI to behave in an out-of-order installation scenario and author an appropriate custom action.  There are a couple of options:

    • Block installation.  You can define and schedule a type 19 custom action to block installation if this property is set.  The custom action must be run after the FindRelatedProducts action, because that action is the one that will search for other versions of the MSI and set the property if any are found.  From the example, this looks like the following:

      <CustomAction Id="CA_BlockOlderVersionInstall" Error="!(loc.LaunchCondition_LaterVersion)" />

      <InstallExecuteSequence>
        <Custom Action="CA_BlockOlderVersionInstall" After="FindRelatedProducts">NEWERVERSIONDETECTED</Custom>
      </InstallExecuteSequence>

      <InstallUISequence>
        <Custom Action="CA_BlockOlderVersionInstall" After="FindRelatedProducts">NEWERVERSIONDETECTED</Custom>
      </InstallUISequence>

      In the example, this custom action is scheduled in both the InstallExecuteSequence table and the InstallUISequence table so that an out-of-order installation will be blocked if the user runs the MSI in silent mode or in full UI mode.

    • Immediately exit and return success.  This requires creating an immediate custom action that returns exit code 5 (ERROR_NO_MORE_ITEMS).  WiX v3.0 has a built-in custom action named WixExitEarlyWithSuccess that can be used to enable this functionality.  To use the built-in custom action, you must make sure that the property created above is named NEWERVERSIONDETECTED exactly like it is in the example I posted.  Then, you must add a reference to the custom action by using the following syntax:

      <CustomActionRef Id="WixExitEarlyWithSuccess"/>

      You must also reference the WixUtilExtension, either by adding it to the references list for your project if you are using Votive and Visual Studio, or by passing it into light.exe with the -ext command line switch.

    A question that I have been asked in the past is why would an MSI want to immediately exit and return success instead of blocking and returning an error in an out-of-order installation scenario?  The primary reason for this type of behavior is backwards compatibility for calling applications, particularly if the MSI is a redistributable component that can be shipped and installed as a part of other products.  Here are a couple of examples of this type of scenario:

    • The .NET Framework 2.0 ships as a part of Visual Studio 2005 setup, and the .NET Framework 2.0 SP1 ships as a part of Visual Studio 2008 setup (inside of the .NET Framework 3.5).  These versions of Visual Studio can be installed side-by-side on the same system, but the .NET Framework 2.0 SP1 performs a major upgrade of the .NET Framework 2.0 so it cannot be installed side-by-side.  If you have the .NET Framework 2.0 SP1 installed and attempt to repair Visual Studio 2005, it will fail with an error because it tries to re-run the .NET Framework 2.0 installer that it shipped with, and .NET Framework 2.0 setup fails because there is already a newer version of that MSI on the system.  It would have been preferable for the .NET Framework 2.0 installer to exit and return success so that Visual Studio 2005 could continue its repair process and return success at the end instead of returning an error.
    • The Games for Windows - LIVE redistributable ships updates as major upgrades.  Games that ship with earlier versions of the Games for Windows - LIVE redistributable need to be able to install and repair successfully even if a newer version of this redistributable is on the system.  This means that the game installer should be able to invoke the older version of the Games for Windows - LIVE redistributable installer that it shipped with and have it return an exit code indicating success in this scenario.

    Step 3: Build version 1 and version 2 of your MSI

    Creating version 1 of your MSI is as simple as running your standard build process - in WiX v3.0, this means you compile and link it with the WiX toolset.  In order to create version 2 of your MSI, you must make the following changes to your setup authoring, then re-run your build process to create a new MSI:

    • Increment the ProductVersion value in the Property table to be higher than any previous versions that you have shipped.  Windows Installer only uses the first 3 parts of the version in upgrade scenarios, so make sure to increment your version such that one of the first 3 parts is higher than any previously shipped version.  For example, if your version 1 uses ProductVersion value 1.0.1.0, then version 2 should be set to 1.0.2.0 or higher (1.0.1.1 will not work here).  In WiX v3.0, you use the Version attribute in the Product element to define the product version.
    • Generate a new ProductCode value in the Property table of the new version of the MSI.

    In the example I created, I included scripts you can run on a system that has a build of WiX v3.0 installed in order to build 2 sets of MSIs:

    • The scripts named build_wix_sample_major_upgrade_block_older_v1.0.1.bat and build_wix_sample_major_upgrade_block_older_v1.0.2.bat will build version 1 and version 2 of an MSI that will block out-of-order installations.
    • The scripts named build_wix_sample_major_upgrade_ignore_older_v1.0.1.bat and build_wix_sample_major_upgrade_ignore_older_v1.0.2.bat will build version 1 and version 2 of an MSI that will immediately exit and return success for out-of-order installations.

    Step 4: Test upgrade scenarios BEFORE YOU SHIP VERSION 1

    This step is very important and in my past experience it has been too often ignored.  In order to make sure that upgrade scenarios will behave the way you expect, you should test upgrades before you ship the first version of your MSI.  There are some upgrade-related bugs that can be fixed purely by making fixes in version 2 or higher of your MSI, but there are some bugs that affect the uninstall of version 1 that must be fixed before you ship version 1.  Once version 1 ships, you are essentially locked into the uninstall behavior that you ship with version 1, and that impacts major upgrade scenarios because Windows Installer performs an uninstall of version 1 behind the scenes during version 2 installation.

    Here are some interesting scenarios to test:

    • Install version 1, then install version 2.  Make sure that version 1 is correctly removed and version 2 functions correctly.  Make sure version 2 cleanly uninstalls afterwards.
    • Install version 2, then try to install version 1.  Make sure that version 1 correctly detects that version 2 is already installed and either blocks or silently exits, depending on what behavior you choose to implement for your out-of-order installation scenarios.

    When testing major upgrade scenarios, make sure to pay particular attention to custom actions in your MSI and assemblies that need to be installed to the GAC or the Win32 WinSxS store.  Here are a few blog posts I've written in the past that contain examples of issues found during major upgrade testing:

    Another more detailed example

    While working on the sample for this blog post, I found the blog post at http://blogs.technet.com/alexshev/archive/2008/02/15/from-msi-to-wix-part-8-major-upgrade.aspx.  This blog post contains more specific details about how Windows Installer behaves behind the scenes during a major upgrade, what information is required in an MSI for major upgrades, and how to map the information in the MSI rows/tables to WiX syntax.  The example in that blog post was created with WiX v2.0 whereas the sample I posted uses WiX v3.0.  The underlying concepts are the same, and the WiX syntax is only slightly different between v2.0 and v3.0.  If you are interested in more detailed behind-the-scenes information about how major upgrades work, and/or if you are trying to implement a major upgrade that uses different settings than the ones presented in my example, I encourage you to check out this blog post as well.

    <update date="3/12/2009"> Fixed broken link to the sample WiX source code for this post. </update>

     

  • Aaron Stebner's WebLog

    Link to more information about Zune device reboots when exiting an XNA Game Studio 3.0 game

    • 2 Comments

    Starting with the Zune 3.0 firmware, you can install and play a set of games on your Zune device.  Texas Hold Em, Hexic, Checkers, Sudoku and Space Battle are available in the Zune firmware and software that is available at the time that I am writing this blog post.

    These in-box games are created with the XNA Framework, but they behave a bit differently than Zune games that you can create yourselves with XNA Game Studio 3.0.  Specifically, many developers have asked on the forums why these games do not require a reboot of the Zune device when you exit them, whereas games created by other developers and deployed to the Zune device using XNA Game Studio 3.0 or via a .ccgame package do require a device reboot.

    My colleague Michael Klucher has posted an item on his blog explaining more details about what is going on behind the scenes in these scenarios and why one set of games requires a device reboot and another set does not.  If you are interested in learning more, I encourage you to read the blog post at http://klucher.com/blog/zune-games-and-rebooting-devices/.

    Also, this scenario has been reported several times via the Connect bug reporting site.  If this scenario is important to you, I encourage you to vote on this existing Connect bug (please vote on the existing bug instead of opening a new bug) so that the XNA will be aware of your feedback as we plan for future versions of XNA Game Studio and the XNA Framework.

  • Aaron Stebner's WebLog

    Installing .NET Framework 3.5 SP1 can succeed in cases where the .NET Framework 3.0 or 3.5 fail

    • 1 Comments

    I previously posted a couple of items about how to troubleshoot and work around issues in .NET Framework 3.0 and .NET Framework 3.5 setup that can be caused by failures in the ServiceModelReg.exe custom action:

    Both of the above blog posts require digging through log files and event logs on your system in order to accurately narrow down the cause of .NET Framework 3.0 and 3.5 setup failures.  In order to hopefully make resolving this type of issue quicker for most people, I wanted to post another option that is much more straightforward:

    If you run into errors when installing the original version of the .NET Framework 3.0, the .NET Framework 3.0 SP1 or the original version of the .NET Framework 3.5, it will sometimes help to simply try to install the .NET Framework 3.5 SP1 instead.

    The reason this can help is that the .NET Framework 3.5 SP1 installs the .NET Framework 3.0 SP2 behind the scenes as a prerequisite.  There is a logic change in the .NET Framework 3.0 SP2 installer that will cause it to continue installing if the ServiceModelReg.exe custom action fails, whereas in previous versions of the .NET Framework 3.0, this failure would cause the entire installation process to fail and roll back.

    If the ServiceModelReg.exe custom action fails during your .NET Framework 3.5 SP1 installation, you may not ever notice if none of the applications you use requires Windows Communication Foundation HTTP activation functionality.  If it turns out that you do need this functionality later on, but the custom action failed during setup and things are not registered correctly, you can manually run the ServiceModelReg.exe tool because it is also installed as a part of the .NET Framework 3.0 and higher.

    I want to mention one caveat here that I typically include in all of my .NET Framework troubleshooting blog posts - there are many possible causes for .NET Framework setup failures, and this blog post only describes one of them.  The above workaround will likely not help solve all possible installation issues.  If this workaround does not help in your scenario, then I suggest looking at the .NET Framework setup troubleshooting guide for links to other possible installation issues and workarounds, links to log file locations, links to readme files, etc.

  • Aaron Stebner's WebLog

    Mailbag: Temporary files can be left behind after running .NET Framework 3.0 or 3.5 setup

    • 7 Comments

    Question:

    I have tried to install the following versions of the .NET Framework on various different computers running Windows XP or Windows Server 2003:

    • .NET Framework 3.0
    • .NET Framework 3.0 SP1
    • .NET Framework 3.5
    • .NET Framework 3.5 SP1

    In some cases, I have noticed that a folder gets left behind on the root of one of my drives.  The folder has a randomly generated name, and it contains a copy of the setup files used to install the .NET Framework.

    I do not see this behavior for the .NET Framework 1.0, the .NET Framework 1.1 or the .NET Framework 2.0.

    Why is this folder left behind at this location after installing these versions of the .NET Framework?  Can I safely delete this folder after I install the .NET Framework?

    Answer:

    The installers for the .NET Framework 2.0 and earlier uses a legacy self-extracting EXE technology called IExpress.  That technology creates a folder in the %temp% directory named something like IXP000.tmp (it will increment the number if a folder with this naming pattern already exists).  Then it extracts the contents of the EXE to that folder and runs the setup EXE from within that folder.  After the setup EXE completes, it will attempt to delete that folder.

    The installers for the .NET Framework 3.0 and later use a different self-extracting EXE technology, which is why you have observed different behavior depending on what version of the .NET Framework you are trying to install.  The self-extracting logic for these versions of the .NET Framework does the following:

    1. Find the drive on your system with the largest amount of free disk space
    2. Create a randomly named folder on that drive
    3. Extract the contents of the EXE to that folder
    4. Run the setup EXE from within that folder
    5. After the setup EXE returns, attempt to delete that folder

    One of the prerequisite packages for the .NET Framework 3.0 and higher - the XML Paper Specification (XPS) Shared Components Pack 1.0 - has a problem that causes the randomly named folder that it creates to fail to be deleted in step 5 above.  Those files are temporary and only needed during the initial installation of this component, so it is safe to delete this randomly named folder if it ends up getting left behind on your system after .NET Framework installation completes.

    I have heard of a few cases where attempting to delete the randomly named folder fails with a permission problem.  I am not sure what causes that type of permission problem in the first place, but you will need to manually update the permissions on that folder in order to be able to delete it.  Tools such as Cacls or SubInAcl could be useful to update these permissions if you run into this issue.

    The XPS component is only installed by the .NET Framework setup package on Windows XP and Windows Server 2003, so the issue where this folder gets left behind at the end of .NET Framework setup will not affect newer operating systems such as Windows Vista, Windows Server 2008 or Windows 7.

    <update date="12/21/2009"> Added more specific information about the root cause of this problem (the XPS setup package that is chained in during .NET Framework 3.0 and higher setup on Windows XP and Windows Server 2003). </update>

     

  • Aaron Stebner's WebLog

    WiX v3.0.4805.0 build is declared an official beta build

    • 1 Comments

    Last week, Rob Mensching and Bob Arnson posted some information on their blogs about the upcoming declaration of a beta build of WiX v3.0 in preparation for locking down WiX v3.0 to get it ready to ship in Visual Studio 2010 (an older 3.0 build is currently available in the CTP).

    This morning, the WiX 3.0.4805.0 build was published to the SourceForge release page (in addition to the normal weekly release page) and declared an official beta build.  Here are links to more information about this build:

    If you're using a build of WiX v3.0 to create your installers, you should upgrade to the 3.0.4805.0 build if possible in order to help validate the fixes that have been made over the past few months and help the WiX development team determine how close WiX v3.0 is to being done and ready to ship.

    You can report issues that you find with the WiX toolset at the following locations:

  • Aaron Stebner's WebLog

    Updated .NET Framework cleanup and verification tools to fix 32-bit registry logic on 64-bit Windows

    • 1 Comments

    While helping out a customer a few weeks ago, we discovered that the .NET Framework cleanup tool and the .NET Framework setup verification tool were not correctly opening, reading from or deleting 32-bit registry values on 64-bit versions of Windows (that is, registry values located under HKEY_LOCAL_MACHINE\Software\Wow6432Node for example).

    As a result, the cleanup tool would leave behind some 32-bit registry values on 64-bit systems that could confuse the .NET Framework setup programs when they were run later on.  Also, the .NET Framework verification tool would skip checking all 32-bit registry values that it was supposed to check on 64-bit OS's, and that could cause it to report successful installs even in cases where important registry keys/values were missing from the system or had incorrect data in them.

    Over the Thanksgiving holiday, I updated both the cleanup tool and the verification tool with fixes to allow them to correctly handle 32-bit registry values on 64-bit OS's.  These changes should not result in any behavior changes when running either of these tools on 32-bit OS's.

    If you previously ran into any issues with either of these tools on a 64-bit OS, I encourage you to download the updated versions and try them again.  Please let me know if you run into any problems with either of these tools.

    For reference, here is additional information about these tools, including download links where you can get the latest versions of each of them:

Page 1 of 1 (7 items)