Thoughts about setup and deployment issues, WiX, XNA, the .NET Framework and Visual Studio
All postings are provided AS IS
with no warranties, and confer no rights. Additionally, views expressed
herein are my own and not those of my employer, Microsoft.
Description of the issue
When installing the .NET Framework 3.5 or Visual Studio 2008 on Windows Vista RTM, some people have noticed that a Windows Update dialog box pops up to indicate that the system must be restarted in order to complete installation of OS updates. The dialog box looks something like the following:
What is happening behind the scenes
Windows Vista includes the .NET Framework 2.0 and 3.0 as OS components. The .NET Framework 3.5 includes Windows Vista OS hotfix packages for the .NET Framework 2.0 SP1 and 3.0 SP1, and both of these hotfixes require reboots in order to complete installation. The .NET Framework 3.5 setup wrapper contains logic to handle these reboot requests and notify the user, but the Windows Update service in Windows Vista also runs in the background and listens for this type of reboot request and pops up dialog boxes like this to notify the user that a reboot is needed as the result of installing an OS update.
Unfortunately, if this dialog appears during the .NET Framework 3.5 setup or during installation of a product that installs the .NET Framework 3.5 as a prerequisite (such as Visual Studio 2008), and the user chooses to restart using the Restart Now button on this dialog, it can cause the system to reboot even if the .NET Framework 3.5 or Visual Studio 2008 setup is still running. This can leave the system in an unknown state if these setups are installing something at the time of the reboot.
How to work around this issue
The Visual Studio 2008 readme will include an item suggesting that the user dismiss or ignore this Windows Update dialog if it is seen during .NET Framework 3.5 or Visual Studio 2008 setup. However, the readme is not always easily found by end users, and this issue can potentially happen for any application that includes the .NET Framework 3.5 setup as a prerequisite on Windows Vista or during unattended deployment of the .NET Framework 3.5.
You can programatically prevent this dialog from appearing when deploying the .NET Framework 3.5. This logic can be included in the script used for unattended deployment or within a setup process that includes the .NET Framework 3.5 as a prerequisite.
Use Windows Update Agent (WUA) APIs to pause the Windows Update service
To implement this solution, whatever script or process you are using to launch the .NET Framework 3.5 setup will use the Pause and Resume APIs on the IAutomaticUpdates interface in the Windows Update Agent (WUA) API set to temporarily pause and resume Windows Update functionality on the system.
You can use steps like the following to accomplish this:
If you call Pause without calling Resume, the operation will eventually time out (the default time out value is 8 hours). Rebooting the system will also cause the Windows Update service to resume without needing to call the Resume method.
<update date="12/13/2007"> Removing option suggesting that users disable the wuauserv service to workaround this issue. Doing this can cause failures during .NET Framework 2.0 SP1 or 3.0 SP1 installation on Windows Vista and should not be used. The valid workarounds are to ignore the reboot prompt or use the WUA Pause and Resume APIs </update>
If I read this right, this is a catasrophe, isn't it?
No one can safely deploy the 3.5 framework with their applications without adding this custom code to their installer?
Surely the 3.5 installer is the place to be including the code to inhibit the OS behaviour?
Framework deployment is still the biggest psychological barrier to shipping .NET applications - why would MS inflict this kind of nightmare on us all, when it could have been dealt with by the framework installer?
Hi WillDean - I think calling this scenario a "nightmare" or a "catastrophe" is too strong of a statement. The reboot dialog that appears in this scenario does not automatically cause a reboot - it only reboots if the user clicks the Restart Now button. In many cases, users are not watching the system closely enough to notice that dialog, or they will not choose to restart with that dialog because they realize that another setup is running.
Ideally, the .NET Framework 3.5 setup would contain this workaround logic, but unfortunately the issue was found too late in the beta process in order to get it fixed in time.
One important note - this issue will only affect systems that do not already have the .NET Framework 2.0 SP1 and/or 3.0 SP1 installed. Future hotfix rollups and service packs for Windows Vista will more than likely include 2.0 SP1 and 3.0 SP1, and therefore will not ever run into this issue.
But haven't you just described the nightmare scenario?
1. Application installer starts 3.5 framework install
2. 3.5 installer installs 2.0SP1 and 3.0SP1 and then starts to install 3.5
3. User notices OS reboot message and presses OK
4. Machine reboots in the middle of 3.5 install
5. Upon restart, machine has broken 3.5 install - I would imagine that there's a very high risk that this broken 3.5 install will prevent the 3.5 install running again - or is that not the case?
If it is, then as a 3rd party developer it's now my problem to get the appropriate cleanup tools onto the end-user's machine to allow the 3.5 install to be cleaned-up and retried.
And all this because the poor user agreed to a suggestion that the OS made to them?
I dread to think how bad your dreams must be if this *isn't* a nightmare. Let's hope the framework SP's are pushed as critical updates as quickly as possible.
Or have I misunderstood the whole thing?
Hi Willdean - Yeah, I agree that the worst case scenario here is a nightmare, but I don't think it is a very likely end user scenario overall, which is why I don't think that I'd call it a "nightmare" overall. For example, if I initiate a setup on my system, I am not going to respond to a reboot request not displayed by that setup until after the setup finishes. (or maybe I've just been working with setups too long and have gotten less scared of issues like this over time)
In addition, the Postpone button appears to be the default button on this OS reboot prompt, so users are not too likely to accidentally press Enter and cause a reboot to happen. Finally, the reboot prompt will happen after installing 2.0 SP1 and 3.0 SP1, but the time that it takes to install the remaining part of the .NET Framework 3.5 is relatively fast (1 minute or less on most of the systems I've seen), so the user would have to be actively looking for this dialog and respond to it pretty quickly to fall within the time window required to put the system in a bad state.
Depending on the exact time when the reboot is initiated out from under the .NET 3.5 setup, it may or may not be recoverable by simply re-running .NET 3.5 setup. From what I've seen in the past, nearly all cases are recoverable without needing to resort to cleanup tools, etc.
I definitely agree that something like this could have been handled better within .NET 3.5 setup, but unfortunately that isn't the case, so I wanted to post a warning just in case folks run into this type of issue in their .NET 3.5 deployment scenarios. I think it is something worth keeping in mind but not necessarily something to panic about.
Sorry, Aaron, but I agree with Will. This is a horrible bug that WILL bite people in the butt. How do I know? Well, partly because I encountered this exact bug when installing Beta 2. It hosed my machine (yes, I clicked reboot now - partly because the install was taking so long and with so little feedback). And I'm a professional software developer.
I really don't think that taking the optimist approach and counting on people to be smart enough to not click the button is a good move. People will do it, I guarantee. You're fooling yourself if you think they won't.
Hi Kevin Dente - I'm definitely not trying to say that it won't ever happen - I've seen repeatedly in the past that as long as the code path is reachable some percentage of people will hit it over time. I also wasn't intending to come across as overly optimistic. I was simply trying to point out some of the mitigations that I think make this problem not likely to affect a large number of people in the grand scheme of things. The mitigations I point out don't mean that the issue won't ever happen, but I think they do mean that calling this scenario a nightmare or a catastrophe in a general sense is a bit too strong.
That doesn't imply that it could be a nightmare for a specific machine where a premature reboot does occur. However, even in cases I've seen where that happened so far, re-running .NET 3.5 setup allowed the system to recover. I also realize that this type of smooth recovery won't be possible 100% of the time, but that is also true for any number of other possible points of failure during any product installation.
It would definitely be ideal if .NET Framework 3.5 setup handled this behind the scenes. Unfortunately, it does not. As a result, other types of mitigations, including further education about the issue via readmes and blog posts have to be considered. That was the intent of this blog post - to try to help people who will be deploying the .NET Framework 3.5 more aware of this potential issue.
One other thing I should add - if you run into the error scenario that is possible as a result of this issue, I strongly encourage you to report it as a bug on the Connect site (http://connect.microsoft.com/visualstudio) to help the .NET Framework setup team get a better understanding of how often this issue happens "in the wild" - this can help lead to improvements in future versions of the .NET Framework installer.
Kevin, I think you and I live in a different world to Aaron.
If I auto-updated 100000 copies of this to one of my clients' retail user-base next week (of course, I won't), I don't think that readme.txt 'education' or filing bugs on Connect are going to be much comfort.
If 1% of those users click 'reboot' when they're asked to (aren't we trying to train them to obey security instructions?) and 1% of them subsequently have install problems, I shall still lose a week's-worth of time trying to help people on the other side of the world get their computers going again.
The sad truth for MS is that, of course, for applications like that one, which absolutely HAVE to install and run without any pain, we use statically-linked MFC/ATL/C++, and we don't use MSI, either.
I *love* programming with C#/.NET, but I suspect I'm not alone in thinking that it would be one hell of a risk in the wild for a high-volume end-user deployment. That there are screw-ups like this being shipped 4 versions of the framework into the whole .NET thing makes me certain that I care more about this kind of stuff than MS do.
You guys know what the bug is, and know what the fix is *BEFORE* you've even shipped the product, but you'd rather make it my problem than deal with it yourselves.
I'm assuming this problem exists in the beta 2 redistributable.
Is it slated to be fixed in the official release?
Hi Bgreenberg - This issue exists in the beta version and unfortunately is not slated to be fixed in the final release either.
I don't want to pile on, but my team ships a mass marketed consumer package that depends on .NET. We currently install the .NET 2.0 redist, if required, as the first phase in our installer. We have some other 3rd party dependencies as well.
In order to ensure smooth installation, we must trap ALL reboot requests and prompt the user in a way that makes sense in our installer flow. If there is any possibility for a premature reboot, this becomes a "very serious issue," if not a nightmare, for our support team. As others have mentioned, I am disappointed that the .NET team allowed this one out the door.
That said, thank you for thoroughly explaining the issue and providing a workaround. Does anyone know if there is an easy way to use the WUA API via MSI custom action?
Aaron Stebner reports an issue (some commenters call it a "nightmare") in the .NET Framework
Si se pot descarca de pe MSDN . MrSmersh adauga un discleimar "handle with care" din cauza unei probleme
This is clearly a bug that every commenter here would consider a RELEASE BLOCKER.
At the very least I would expect a sample project with the necessary workaround code.
Releasing a bug like this with nothing but an entry in the readme and a blog post is nothing sort of shameful. Who knows what kind of damage or unexpected results can happen from all the service-manipulating workaround code developers are going to have to put into their installers?
Of course, I don't know what's worse, that the .NET Framework doesn't stop the reboot message or the Windows installer can't handle a reboot request without borking a user's system. Considering how incredibly over-engineered the whole system is and how it runs with SYSTEM-level access I would expect it to be more robust.
This "it's not that bad and there are workarounds" seems indicative of the attitude in the recent Windows Update controversies and really among the whole Vista release. Sloppy and unprofessional, Microsoft.
(Nothing against you, Aaron, you're probably as upset about this as we are and are stuck taking the flack since you're the one with helpful blog.)
The nightmare scenario is alive and well. There is no .NET Framework 2.0 SP1 or .NET Framework 3.0 SP1 install package available for Windows Vista.
As an app dev I will be relying on the .NET Framework 3.5 installation / bootstrapper to do the proper installation.
Now that I have to code workarounds within my installation for Vista, this is a huge barrier to .NET Framework 3.5 acceptance / installation for my application.