Saturday, January 19, 2008

MSI Installer

To get the MSI installer to remove the "Just Me" option so that "Everyone" was the default option was no easy task. First, most instructions on the web tell yout o edit the msi file yourself, which is a big buzz kill. You mean you want me to open up the msi file, dig through the property and table, and edit a variable like I was doing some kind of registry edit? Every time I compile? Fortunately, there are some knowledgable people out there. And you can switch what the default is, so that you can recompile, and it would be compiled with the right options. And I figured out how to hide the option from showing. Unfortunately, when you do an unattended installation, this change you make doesn't matter. And I found a fix, on one of microsoft's guy's blogs. According to google, he's the only guy that's posted information on how to do this. For the record the built in installer to vs .net 2003 sucks.

http://blogs.msdn.com/mollman/archive/2004/09/07/226483.aspx

For the sake of perserving the information he has put up, just incase these Microsoft pages disappear, like they do on any microsoft website, I've decided to cut and paste his post, so I can personally refer to it later:

Windows Installer: Installing for Everyone in a Silent Install
[updated: cleaned up links]I got bitten last week by a subtlety in the way Windows Installer packages generated by Visual Studio 2003 handle installing for everyone rather than the default "Just Me" when being run as a silent install. Maybe less a subtlety in the installer than a gap in my understanding of the installer's workings. At any rate; since I had a more difficult time than I thought I would finding the right answer I figured I'd post it here so Googlers everywhere can find it easily.
Creating an installer package from within Visual Studio 2003 is pretty simple and straightforward. For many simple deployment scenarios creating a new project of type "setup project" and adding the primary output of another project in your solution gets you most of the way there. Visual Studio does a good job of exposing the properties of the underlying MSI database as design-time properties.
One common scenario that isn't covered by Visual Studio 2003 is setting the default value of the "Install for . . ." option in the setup routine from Visual Studio. The default value is "Install for Just Me," and oftentimes you'll want/need to default to "Install for Everyone" instead. This is a per-machine installation rather than a per-user installation in Windows Installer parlance.
In order to accomplish this you need to open the MSI package Visual Studio generates for you using a tool like Orca (part of the Windows Installer SDK, which is part of the Platform SDK. Get it at http://www.microsoft.com/msdownload/platformsdk/sdkupdate) and edit the database manually.
To default to a per-machine installation you simply change the value of the FolderForm_AllUsers property (in the properties table) from "ME" to "ALL." This is all you need to do in scenarios where you are presenting the user with a UI in that the value of the "Install for" radio button will now default to "All Users" which is what you want.
The problem I hit was that this doesn't cover the cases where no (or a limited) UI is displayed to the user. In my case our Operations team was deploying my app to a cluster of servers using a remote shell to execute msiexec with the /q option (no UI). I'd thought the underlying default property would be passed through in this case regardless of the presence of the UI, but I was wrong. To cover this case you need to add an additional property to the MSI.
To ensure that the installation defaults to Everyone in a silent install, create a new property in the properties table named "ALLUSERS" and set its value to "2" By default this property doesn't exist in the Visual Studio generated MSI, so it's value is unset, which indicates a per-user installation. If only users with Administrative privileges should be able to install your package you can set this property to "1" in which case the installation will fail if the installing user doesn't have admin rights. Setting "ALLUSERS" to "2" will attempt to do a per-user install if the per-machine install fails because the user doesn't have administrative privilleges.
If you've set this property because you don't want users to be able to install for "Just Me" (as was my case) you'll want to remove the option of setting this property in the UI. You can also either get rid of the dialog that offers the choice altogether or hide it if you don't want to offer the choice to your users.
In my case I hid them by dropping all the rows for the "AllUsersRadioGroup" and "AllUsersText" actions (there are 2 actions per control for these -- a hide and a show. Drop them all) from the ControlCondition table. I then set the attributes for the "AllUsersRadioGroup" and "AllUsersText" controls in the Control table to "2".
That was all it took, and I could stop blocking the release of an entire suite of projects to our production environment ;-)
More information on using Orca can be found here.
More information on per-user and per-machine installs can be found here.

1 comment: