IIS 7 provides a rich extensibility model, whether extending the server or the user interface, one critical thing is provide a simple setup application that can install all the required files, add any registration information required, and modify the server settings as required by the extension. Visual Studio 2008 provides a set of project types called Setup and Deployment projects specifically for this kind of applications. The output generated for these projects is an MSI that can perform several actions for you, including copying files, adding files to the GAC, adding registry keys, and many more. In this document we will create a setup project to install a hypothetical runtime Server Module that also includes a User Interface extension for IIS Manager. Our setup will basically perform the following actions: • Copy the required files, including three DLL’s and an html page. • Add a couple of registry keys. • Add the managed assemblies to the GAC • Modify applicationHost.config to register a new module • Modify administration.config to register a new UI extensibility for InetMgr • Create a new sample application that exposes the html pages • Finally, we will remove the changes from both configuration files during uninstall
Start Visual Studio 2008. In the File Menu, select the option New Project. In the New Project Dialog, expand the Other Project Types option in the Project type tree view. Select the option Setup and Deployment type and select the option Setup Project. Enter a name for the Project and a location. I will use SampleSetup as the name.
Adding assemblies to the setup is done in the same File System editor, however it includes a special folder called Global Assembly Cache that represents the GAC in the target system. In our sample we will add to the GAC the assemblies that have the runtime server module and the user interface modules for IIS Manager. I have created the following set of projects:
Back in Visual Studio,
Visual Studio also includes a Registry editor that helps you adding any registry keys in the target machine. For this sample I will just add a registry key in HKEY_LOCAL_MACHINE\Software\My Company\Message. For that: Select the menu option View->Editor->Registry. Expand the HKEY_LOCAL_MACHINE node and drill down to Software\[Manufacturer]. [Manufacturer] is a variable that holds the name of the company, and can be set by selecting the SampleSetup node in Solution Explorer and using the Property Grid to change it. There are several other variables defined such as Author, Description, ProductName, Title and Version that helps whenever dynamic text is required. Right click [Manufacturer] and select the option new String Value. Enter Message as the name. To set the value you can select the item in the List View and use the Property Grid to set its value. After completing this, the project should look as follows:
To support any custom code to be executed when running the setup application, Visual Studio (more explicitly MSI) supports the concept of Custom Actions. These Custom Actions include running an application, a script or executing code from a managed assembly. For our sample, we will create a new project where we will add all the code to read and change configuration. Select the option File->Add->New Project. Select the Class Library template and name it SetupHelper.
As you can see the code above is actually really simple, it just calls helper methods in a utility class called InstallUtil that is shown at the end of this entry. You will also need to add the InstallUtil class to the project to be able to compile it. The only interesting piece of code above is how we pass the TargetDir from the Setup project to the Custom action through the Parameters property of the InstallContext type.
To be able to use our new Custom Action we need to add the SetupHelper output to our setup project, for that: Select the option View->Editor->File System Right-click the Application Folder node and select the option Add Project Output... and select the SetupHelper project in the Project drop down.
After doing this, the DLL will be included as part of our setup.
Select the option View->Editor->Custom Actions Right-click the Install node and select the option Add Custom Action… drill down into the Application Folder and select the Primary output from SetupHelper.
Click OK and type a name such as InstallModules
Now, since we want to pass the TargetDir variable to be used as the physical path for the web application that we will create within our Installer derived-class, select the custom action and go to the Property Grid. There is a property called CustomActionData. This property is used to pass any data to the installer parameters class, and uses the format “/<name>=<value>”. So for our example we will set it to: /TargetDir="[TARGETDIR]\"
In the same editor, right-click the Uninstall node and select the option Add Custom Action…, again drill down into the Application Folder and select the Primary output from SetupHelper. Press OK and type a name such as UninstallModules. After doing this the editor should look as follows:
Finally we can build the solution by using the Build->Rebuild Solution menu option. This will create a file called SampleSetup.msi, in the folder SampleSetup\SampleSetup\Debug\SampleSetup.msi You can now run this MSI and it will walk through the process of installing. The user interface that is provided by default can also be configured to add new steps or remove the current steps. You can also provide a Banner logo for the windows and many more options from the View->Editor->User Interface.
Visual Studio provides different packaging mechanisms for the setup application. You can change it through the Project Properties dialog where you get the option to use: 1) As loose uncompressed files. This option packages all the files by just copying them into a file system structure where the files are copied unchanged. This is a good packaging option for CD or DVD based setups 2) In setup file. This option packages all the files within the MSI file 3) In cabinet files. This option creates a set of CAB files that can be used in scenarios such as diskette based setup.
You can also customize all the setup properties using the property grid, such as DetectNewerInstalledVersion which will warn users if a newer version is already installed or RemovePreviousVersion that will automatically remove older versions for the user whenever he tries to install a new one.
Turns out that the managed code custom action will fail under 64-bit platform due to it being executed as a 32-bit custom action the following blog talks about the details and shows how you can fix the issue:
Visual Studio 2008 provides a simple option to easily create Setup applications that can perform custom code through Custom actions. In this document we created a simple custom action to install modules and InetMgr extensions through this support.
For the latest information about IIS 7.0, see the IIS 7 Web site at http://www.iis.net
This is the class that is used from the SetupHelper class we created to do the actual changes in configuration. As you can see it only has six public methods, AddModule, AddUIModuleProvider, CreateApplication, RemoveApplication, RemoveModule, and RemoveUIModule. The other methods are just helper methods to facilitate reading configuration.