Peter Kjaer (SDL)

February 10, 2012

Building the PowerTools installer

Filed under: PowerTools — Tags: , , , , , , — Peter Kjaer @ 4:50 PM

This week, I’ve been working on creating an installer for the PowerTools project.
In this post I will go through some of the lessons I learned, while giving a general overview of the new installer.

Requirements

Before creating an installer, it’s a good idea to know what you need it to do.
For the PowerTools project, we settled on the following requirements:

  1. Developers should not have to install additional software in order to build or update the installer. This ruled out frameworks familiar to me, such as WiX.
  2. The installer must install the Editor and Model files into a new “PowerTools” folder. By default the folder should be underneath the Tridion installation folder, but the user should be free to choose a different location.
  3. It must create the virtual directories required for the Editor and Model, under the existing SDL Tridion 2011 website.
  4. It has to update the System.config file to add the Editor and Model configuration required for the extension to load.
  5. It should be possible to uninstall and optionally to repair the installation.

With the above in mind, I decided to try the “Setup Project” templates that come with Visual Studio 2010.

Choosing the right project template

The first thing I noticed when I tried to create a Setup Project, is that there are multiple templates for it.
For our purposes, I quickly ruled out the Merge Module and CAB Projects; those are mainly used to include your deployed files in other installers.

So I was left with a choice between “Web Setup Project” and just “Setup Project”. Although “Web Setup Project” initially seemed like the best choice (with its ability to create virtual directories easily), it turned out to be too hard to modify to fit our requirements. Mostly, this was due to the unusual situation that we wanted to install everything under existing folders and on an existing website.

A basic installer

With the Setup Project, it’s easy to do the basic things:

  • Add files to be installed by going to View | Editor | File System. You can add specific files if you want, but mostly you should add the output from other projects in the solution. This includes the Primary Output (assemblies in this case), Content (ASPX pages, images, CSS files, etc.), Localized resources for translations, etc. With this approach, new files added to the other projects will automatically be included in the installer.
  • You can exclude files by right-clicking on one of the above entries and entering an ExcludeFilter – or if it is listed in the Detected Dependencies list of your Solution Explorer you can just right-click on it and choose Exclude. This was useful for DLLs we needed to reference, but expected to be installed on the machine already (e.g. Tridion.Web.UI.Core.dll)
  • You can change what is displayed on the different installation screens by going to View | Editor | User Interface. The Properties of each screen have some limited changes you can do (for instance, I removed the default copyright statement by editing the Properties of the “Welcome” screen.
  • You can search for required files or registry keys by going to View | Editor | Launch Conditions. I used this to load the installation folder for Tridion Content Manager Explorer as well as the website details. The value is then available for later use, in a variable name of your choosing. These variables can then be used as the default values for installation folders or passed along as parameters to Custom Actions.
  • There are more Editor views available, but those are the important ones for this particular installer.

Custom Actions

Two of our requirements could not be done in the screens I just mentioned:

  1. Creating the virtual directories in IIS.
  2. Updating the System.config XML file.

For those requirements, I needed to implement “Custom Actions” – which is basically custom code that you can run within the installer.

You can call a Custom Action for 4 phases of the installation: Install, Commit, Rollback, and Uninstall.
To define a Custom Action you create an “Installer Class” file – a class that inherits from System.Configuration.Install.Installer and has a RunInstaller attribute.

The class should be created in an assembly that is available when the installer runs, meaning it should be in a DLL that is installed on the target system. That way it can also be run when uninstalling.

For the PowerTools installer, I added a class called “CustomActions.cs” in an “Installer” folder under the PowerTools.Common project.
I then added the assembly under each install phase on the View | Editor | Custom Actions screen.

The custom action class implements the remaining requirements. There were only two tricky parts to this:

  1. Reading variables such as the installation folder and the CME directories.
    This requires that you set a CustomActionData Property on the  relevant item in View | Editor | Custom Actions.
    See below for some notes on the precious format you are supposed to use.
  2. You need to use the “state” object that is passed into each of the 4 methods to maintain state such as exactly which virtual directories were created.
    You can then use this state when rolling back the installation or uninstalling.

Gotchas

Finally, I want to cover a few things you may run into, that are not entirely obvious.


There’s Properties and then there’s Properties

In Visual Studio there are two different kinds of “Properties” you can edit:

  1. Property Pages (Alt+Enter / Shift+F4)
  2. Properties Window (F4)

Both of these have the title Properties and for many items they are identical.
However for projects and a few other select files, the Property Pages show up by default and you have to specifically select the item and press F4 to see the Properties Window.

It does actually make sense, but it took me a while to find the property I was looking for because I was only seeing the Property Pages when I right-clicked on the project and selected Properties.


CustomActionData format

The CustomActionData property follows a very specific format and is a little fragile.
You need to:

  • Separate each parameter with spaces.
  • Use double-quotes around anything that might have spaces in them.
  • Follow the format /paramName=paramValue
  • Use square brackets around variable names such as TARGETDIR (which holds the main selected installation folder).
  • End the value with a backslash if it even resembles a file path. On one occasion, I had to do this even when the value already had a backslash at the end (and then I had to trim it again afterwards).

Example format from the current installer:

/CME_WEBSITE_ID=”[CME_WEBSITE_ID]” /TARGETDIR=”[TARGETDIR]\” /CME_WEBROOT=”[CME_WEBROOT]\”


Changing the application icon

You cannot change the icon that is displayed for the MSI itself. It’s not possible, for reasons that escape me.

But you can define the icon that is displayed in the Add/Remove Programs list by adding the icon to the File System list and choosing it as the AddRemoveProgramsIcon property of the installer project (in the F4 version!).
You can then exclude the icon from being installed if you don’t use it in the actual installed software.


How to ruin your uninstall capabilities

You need to be careful with exceptions in the Uninstall step or Custom Action. If you mess it up, you will be unable to remove the software again without manual action.

If you do have a broken uninstall, try the following:

  1. Fix the code so that a new install will not have the same problem.
  2. Remove the registry entries for the installer under HKEY_CLASSES_ROOT\Installer\Products. You will have to browse through them one by one until you find your installer.
  3. Install the fixed version. Your uninstall should work again.


Rebuilding and troubleshooting

Occasionally, I found that my changes were not being picked up.
I think this happened when I just build the solution. In this case, it doesn’t rebuild the installer (unless there are direct changes to the installer).

For that reason, I recommend specifically rebuilding the installer by right-clicking on the project and selecting Rebuild.

Also, it is not easy to dynamically debug a running installer. However, you can force a debugging session to start by putting this in the code:

System.Diagnostics.Debugger.Launch();


Enough talk

Alright, that’s probably more than you wanted to know about the PowerTools installer.
If you are still interested, have a look at the source code.

Also, if you feel like actually testing out the installer (on a 2011 SP1 system), your feedback would be much appreciated!
It can be found in the Downloads section of the Google Code project.

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: