The .NET Framework 4 Installer Improvements

The .NET Framework 4 Installer Improvements

  • Comments 19

Much of this is a repost of my Beta 2 post with updated content and data.

Thanks to everyone that gave feedback both on my blog and through other forums about .NET Framework installs. .NET 4 just released so I thought I’d take this opportunity to talk a little about the stuff we have done to improve the installation. My team and I have been focused over the past year on incorporating feedback and striving to make the installer better for the .NET Framework 4. There has been a particular focus on making it better for client applications to install it with their apps.

The key focus areas for the .NET 4 installer have been Size, Robustness, and Performance. I’ll speak to some of the major things we did and give a brief description below.

Size

You can see from the chart below that we have reduced the size of the .Net redist significantly. It went from client applications needing to carry 237MB to 41MB for the client profile. This is a game changer for a lot of client applications.

Size Comparison of the redist size since 3.5 SP1

  3.5 SP1 4 Beta1 4 Beta2 4 RTM
32bit Client Profile X 34.5 MB 31.5 MB 28.8 MB
32bit Full X 77.5 MB 38.5 MB 35.3 MB
32+64bit Client Profile X 72.5 MB 48.2 MB 41 MB
32+64bit Full 237 MB 162.6 MB 55.9 MB 48.1 MB
 
Better Compression Across Packages

We implemented the use of a better compression technology into our packages which reduced the size of our packages by around 15%.

Separate packages for AMD64 and IA64

We found that there was little to no need to ever install the same package on both amd64 and ia64. Because of this, we decided to produce amd64 packages that excluded ia64 binaries as well as ia64 packages that didn’t contain amd64 binaries.

Client Profile

We determined the subset of framework functionality that was used by 95+% of client applications and produced a first class package for this scenario. The result of this is that, unless you are taking advantage of features such as ASP.NET, you can now take a dependency on a smaller framework. More details of what is in the client profile can be found here.

Remove Duplicate MSIL

We identified many assemblies that were functionally identical but differed by the architecture they were built under. These assemblies were all managed CPU neutral assemblies which meant that it didn’t matter whether they were built for x86 or amd64. Their strong names and functionality are the same. We solved this by only carrying one of them.

Robustness

The numbers are already starting to come in from the RTM release and we are very happy with the success rates of the install. At this point we are seeing greater than a 99% success rate which is much better than previous .NET redist releases right out of the gate. Here are some of the larger things we did to increase robustness.

Remove Prerequisites

In a chain of installs, the chain is only as strong as its weakest link. In addition, small weaknesses in each part of the chain compound to lead to higher failure rates for the whole chain. By removing numerous prerequisites and combining the whole client install into a single MSI, we were able to get rid of the compounding effect of failures as well as focus our efforts on making the single MSI as solid as possible.

Simplify the MSI

Custom actions are very common places for installs to fail. The more you have, the more complex the installer gets and the number of points of failure goes up. Removing the need for customactions in many cases and in the cases where we needed them, simplifying them has increased our success rates.

Remove slipstreamed feature MSP’s

In Beta1, we slipstreamed features into the installer’s msi using patches. This proved to be a point of complexity and the root cause of many unsolvable bugs. Due to that, we simplified our install to be completely contained in a single msi per platform.

Fix and Retry

    Through thorough investigation of our past installers, looking through KB articles, feedback from customers, and through our past Beta’s, we found numerous install failure conditions that were fixable after the error. We implemented the KB articles and other workarounds so, in failure cases, we can fix the users machine and try again. We’ve seen quite an increase in our success rates due to this work. My hope is that this will also make the windows installer ecosystem cleaner and that msi’s installed after .NET 4 will have a better chance to succeed because our installer put the machine in a better state.

    Triple fallback on Download failures

    Through analysis of our download failures in the past, we determined that using a single implementation for downloads left you only as successful as that technology allows. We found that between Winhttp, URLMon, and BITS, their failures were in different scenarios and where one would fail, the others would succeed. In order to take advantage of this, our chainer falls back and retries on different download stacks to do everything we can to get a successful download.

    Separated out Server configuration from Client Profile

    The Client Profile installer should be more robust for applications now because some of the most common failing custom actions in .NET 3.5 were in configuring things like ASP.NET and WCF which are mainly server scenarios and not used by client applications. By moving these to the full install, we are seeing higher success rates for the client install.

    Performance

    The key metric here is overall install time for the redist. In 3.5 SP1 the average install time was 12-15 minutes. With v4, the average times are closer to 3-5 minutes for the client profile and 5-7 minutes for Full.

    Smart Cabbing

    Smart cabbing is a technique used to allow you to install the same file to multiple locations but only carry the file once in the msi’s cabs. This technique has been used for years but during our perf investigations, we found that, depending on how many duplicate files there were and where they were in the cab, performance degraded significantly. We made some bug fixes in the tools we use to smart cab (WiX) to reduce the impact of duplicated items while still gaining the benefits of smart cabbing.

    Remove Prerequisites

    This one is fairly self explanatory. We need to install less packages so we are faster. This is mostly the result of changing the .NET Framework itself to not have certain dependencies or carry subsets of the dependencies within the framework. In a few cases, this was possible because the base functionality was either built into all the supported OS’s or had enough ubiquity in the ecosystem to not warrant us carrying it.

    Remove Slipstreamed Msp’s

    We found that when applying large slipstreams to a product, there was a significant perf hit towards the end of the install when Windows Installer is caching the packages for source resiliency. By adding all the features into the MSI, we got rid of this performance hit.

    Parallel Ngen and removal of synchronous 64bit assemblies

    The CLR implemented the ability to ngen on multiple cores in parallel. We made changes in our installer to take advantage of this so now on a multicore machine, ngen times should be significantly reduced. Also, on 64bit machines, most .NET applications run as 32bit. This means that paying the price of creating 64bit native images is not something most apps need to do.

    Client Profile

    By producing a subset of the .NET install that contains the features most client applications need, most client applications can take advantage of shorter install times by installing less.

    Parallel Download and Install

    If you are using the web bootstrapper which we made available for the first time in Beta2, you can use the web bootstrapper to install .NET Framework 4. This has the advantage of downloading and installing the payload in parallel. For example, as it is installing the Client Profile, it will be downloading the rest of the framework. In cases where you have enough bandwidth to download the rest before the Client Profile install finishes, you essentially save the time it took to download the rest.

    • I know when I was looking at the file size, I wasn't sure I downloaded the whole thing!

      Good job :D

    • I wrote the same comment on beta 2 post (I'm not sure if you still checking it):

      I'm also interested in examples (samples) of bootstrapper. I will appreciate if you can share some samples.

      Did you use Burn as bootstrapper for .NET 4.0? Because I heard that it is not ready yet.

    • Greate job peter. Big thumbs up to you guys. For me this is the most important improvement or feature of fx 4.0. Without this i would have to use 2.0 for future development.  

      Part of the world where i work asia, africa (most part or atleast to most people i would say) net connectivity is not great or costly. and people use XP. Users wont have .net fx and i can't ask them to download bloated installer. This created app distribution problem. so i stuck with fx 2.0.

      Now i can use all the new things since 2.0.

    • @Igor, the codebase the we used to ship .NET 4 is part of the foundation of Burn but there are a lot of general use features that a lot of products need (like feature selection and reboot support) that .NET 4 didn't need. So in a way, yes, we used a early version of Burn to ship .NET 4 but the statement that Burn isn't quite ready yet for general use is also correct.  Look for it towards Sept/Oct timeframe. Rob Mensching's blog is the place to get the latest release info for Burn.

    • If your 2.0 application has v4.0 listed as a supported runtime in its exe.config, then v4 will load it. You can also load 2.0 dll's into v4. Make sure in both these cases you test your application on 4.0 to make sure the 2.0 assets are fully v4 compatible.

    • I just had one of those wild ideas that will come back to bite me...help me out here;

      My app is just about ready to be released.  It runs on .NET 3.5 SP1.  Does the .NET 4.0 installer install all the earlier versions of the framework as well?

      In other words, if I redistribute the .NET 4.0 installer with my app instead of redistributing the .NET 3.5 SP1 installer with my app, will my app still run?

    • There is a good chance your app will run on 4.0 but if you continue to compile targeting 3.5 you will need to add an supported runtime entry in your exe.config so if it can't find the 3.5 runtime it will load on the 4.0 runtime. If you just want it to run on 4.0 and never 3.5, omit the 2.0 runtime as a supported runtime. The order they are listed below determines what will happen if both are available, the first available runtime is the one that it will be loaded in.

      Example:

      <configuration>

         <startup>

             <supportedRuntime version="v2.0.50727" />

             <supportedRuntime version="v4.0" />

         </startup>

      </configuration>

    • "There is a good chance your app will run on 4.0"

      What are the main reasons that the app working on .Net Framework 2.0 could not work after changing framework to 4.0 ?

    • Thank you for your answer! I again feel a hope that I can use Burn, because after last Rob's email I lost my belief, that I will use Burn for "my" installers. I'm still not sure that I will need feature selection and reboot support (because a lot of bootstrappers doesn't support it either).

      Which version (build) did you use for .net 4.0?

      Can you please post some examples how to use it, because currently almost zero information is available about it.

      Thank you in advance!

    • @Chris - here is a migration doc that talks about the changes and the recommended fix to properly run on 4.0. http://msdn.microsoft.com/en-us/library/ee941656.aspx

      Hope this helps...

      Note: I've migrated a few aps by just using the exe.config to run on .NET 4 and they just worked but that wont be the case for all apps depending on what .NET features they use.

    • @Igor - We didn't use a WiX build for our chainer. The codebase that we had for our chainer got merged into burn a few months ago. There isn't a WiX build that you can pick up to get exactly the chainer we used for .NET 4.

    • Thank you for clarification. So mainly it won't be the same if I will use Burn from lastest build and most probably Wix Team won't have time to finish all merging till autumn.

    • Thats a good way to put it. Even samples right now would be premature because the schema is under development and the build process is also being defined.

    • How do you go about deploying .net 4 using group policies? using the msi does not work, errors with use setup.exe to install, it also  doesnt allow an admin install.

    • Admin installs are documented here: http://msdn.microsoft.com/en-us/library/ee390831.aspx

      Group policy deployment is not supported.

    Page 1 of 2 (19 items) 12
    Leave a Comment
    • Please add 8 and 8 and type the answer here:
    • Post