Moving into Del Boca Vista with the Costanza's (Completed)

The last step in the Vista-related improvements I outlined several months ago involves improving the bootstrapper experience on Vista. The problem is that running the bootstrapper on Vista gives a UAC elevation prompt as soon as it is launched. Despite what you may have heard, the bootstrapper isn't some terribly sophisticated piece of software engineering. Really, all it does is launch processes. When the bootstrapper is elevated, the children processes it launches are also elevated. This is both a blessing and a curse. On the one hand, if the bootstrapper is running other installers, those probably should be elevated. On the other hand, it's not always necessary to elevate the final application install (which we refer to as the "caboose"), for example when installing a ClickOnce application or installing an MSI which has the LUA Aware bit set.

One tempting solution to this problem is to not have the bootstrapper prompt for elevation up front. Its the OS that is causing this prompt to come up, but there is a way to tell the Vista to not prompt for elevation: you can add a manifest to setup.exe so that no eleavtion occurs. And that is correct, this will help the situation of launching the caboose elevated. But it breaks any bootstrapper that needs to install prerequisites, because those packages will need to be elevated.

"But Mike," you argue, "won't the auto-elevation features of Vista get this solution to work? After all, when I try to run my SQL Express installer manually an elevation prompt comes up." Unfortunately, its not that simple: Vista will issue the prompt for the prerequisites only when the installer processes are launched in a specific manner. Namely, the process has to be launched with ShellExecuteEx, and specify the verb as "runas". Of course this wasn't known at the time the bootstrapper was getting developed, and as a result that's not how the bootstrapper works. So simply adding a manifest to your setup.exe won't work.

A more exotic solution is to have the bootstrapper change how the caboose is launched. This is possible to accomplish because of how the bootstrapper is architected: if the caboose is an MSI, it uses MsiInstallProduct to install the MSI. Otherwise, it does a ShellExecute on the caboose. So, if the caboose were actually an executable that would launch the MSI for us, that might work instead. Well, almost: when the bootstrapper is elevated by Vista, the caboose will also be elevated.

So, the solution needs to get even more exotic: create one executable that is not elevated, which launches the original setup.exe (specifying the "runas" verb), waits for that to finish, and then installs the MSI. And on the surface, this doesn't seem too hard: once again, all that's basically happening is that process are launched, and something waits until each process is finished before launching the next process. In this case there would be 2 child processes: the original bootstrapper (which may launch additional child processes), and then MSI install. And this would be pretty easy except that some of the child processes launched by the original bootstrapper may cause the machine to reboot. Suddenly this becomes a lot harder: now, this new bootstrapper has to detect when the original bootstrapper is causing a machine reboot, and needs to deal with restarting the original bootstrapper when coming out of the reboot.

I am fully convinced that I could still create a bootstrapper that deals with all of these scenarios. But I won't. The fact of the matter is, the user experience would still be far from ideal, and getting this "uber-bootstrapper" technique fully tested enough to publish to the web just won't happen in a timely fashion. If this were 2006 instead of 2007 and Visual Studio 9 weren't right around the corner, I would make the time. But the fact of the matter is that VS 9 is going to fix this problem for us (with a better solution than I could come up with on this blog), so there's not much sense in writing a blog post thats going to be completely obsolete in a matter of months. And yes, the Visual Studio 9 solution will be free (as part of the Windows SDK) and can be used on Visual Studio 8 projects (I plan on blogging about that once the SDK is officially released).

So, that will wrap up the Vista-specific post-build steps I wanted to blog about. I'll summarize them below, along with a few words about how Visual Studio 9 (aka Orcas) will address those issues.

Making Custom Actions run without impersonation
Orcas will be making all custom actions NoImpersonate.

Create non-advertised shortcuts
Orcas will continue to have all shortcuts be Advertised, so you might want to hold onto these steps.

LUAAware bit
Orcas won't provide any means to access the LUAAware bit.

Shield Icons
No Vista-related changes to standard Windows Installer dialogs are coming in Orcas.

Bootstrapper Improvements
Improvments were made in this area. A manifest was added to setup.exe to not force elevation on Vista. The corresponding changes to how the prerequisites (with the "runas" verb) were also made. As a result, there is no elevation prompt when the bootstrapper is launched, and therefore the caboose install will not automatically be elevated. However, there will be an elevation prompt for every prerequisite that is installed on the machine. So, if your application needs the 3.5 .NET Framework as well as SQL Express, installing your applicatoin via the bootstrapper will cause 2 elevation prompts (1 for each of the components). But this is much better than the VS 8 behavior, which caused an elevation prompt even if nothing was installed.