Thanks to everyone that gave feedback both on my blog and through other forums about .NET Framework installs. Beta2 just got released on MSDN 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.0 . 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.0 installer have been Size, Robustness, and Performance. I’ll speak to some of the major things we did and give a brief description.
Comparison Chart for Size improvements since 3.5 SP1
|3.5 SP1||4.0 Beta1||4.0 Beta2|
|32bit Client Profile||X||34.5 MB||31.5 MB|
|32bit Full||X||77.5 MB||38.5 MB|
|32+64bit Client Profile||X||72.5 MB||48.2 MB|
|32+64bit Full||237 MB||162.6 MB||55.9 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.
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.
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 and increase in our success rates due to this feature. My hope is that this will also make the windows installer ecosystem cleaner and that msi’s installed after .NET 4.0 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.
Separate 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.
We implemented a new chainer in Dev10 that is being used by 4.0. It is smaller, faster, and more flexible than its predecessor. The flexibility is a major part of what allowed us to make investments such as the download fallbacks, Fix and retry, and better compression. I’m excited that this chainer is the foundation of what is being built into the WiX community under the name of Burn. This should be available for others to use in the WiX 3.5 release.
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.
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.
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.0. 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.