Installing an IIS 7 Extension

Related to cleaning up my authentication module for Codeplex, I needed a way to (semi) automatically install a complete IIS extension (including schema, config sections and management extensions). I came up with a batch file that does the necessary steps (anybody out there that wants to write a real installer?).

1. Register all assemblies in the GAC
Usually an IIS 7 extension consists of at least three assemblies (module/handler, server extensions, client extensions). Gacutil.exe is your friend here (use the /if option). Also take into account, that IIS loads GACed assemblies domain neutral. That means that you have to recycle the worker process when you update e.g. your GACed module.

2. Register schema and config section
This involves copying your schema to the IIS’ schema directory and add a <configSection> registration to applicationHost.config. Mike Volodarsky from the IIS team has written a nice tool call IisSchema that automates this step.

3. Registering the management extension
This involves adding the module to administration.config (in two different places). I haven’t found an automated way of doing this, so I wrote a little tool to accomplish this task.

IisRegMgmt [install/uninstall] [assembly_to_register]

This will find all Microsoft.Web.Management.Server.ConfigurationModuleProvider derived classes in the specified assembly and register them in administration.config.

The code to do the registration is as follows:

private static void RegisterAdministration(string name, string type, string assembly)
{
    // get access to administration.config
    Configuration administration = _manager.GetAdministrationConfiguration();

    // get access to <moduleProviders>
    ConfigurationSection moduleProvidersSection =
        administration.GetSection(“moduleProviders”);
    ConfigurationElementCollection moduleProviders =
        moduleProvidersSection.GetCollection();

    // check for existing elements first
    Clean(name, moduleProviders);

    // create new element
    ConfigurationElement newModuleProvider =
        moduleProviders.CreateElement();

    // set attributes
    newModuleProvider.SetAttributeValue(“name”, name);
    newModuleProvider.SetAttributeValue(“type”, type + “, “ + assembly);

    // add element
    moduleProviders.Add(newModuleProvider);

    // get access to <modules>
    ConfigurationSection modulesSection =
        administration.GetSection(“modules”);
    ConfigurationElementCollection modules = modulesSection.GetCollection();

    // check for existing element first
    Clean(name, modules);

    // create new element
    ConfigurationElement newModule = modules.CreateElement();

    // set attributes
    newModule.SetAttributeValue(“name”, name);

    // add element
    modules.Add(newModule);

    // save changes
    _manager.CommitChanges();
}

Don’t forget to clean up the sections before you add the new module, otherwise you might end up with double entries:

private static void Clean(string name, ConfigurationElementCollection elements)
{
    var hits = from e in elements
               where (string)e.GetAttributeValue(“name”) == name
               select e;

    hits.ToList().ForEach(e => elements.Remove(e));
}

For completeness sake, here’s how you can find the right management classes in the assembly (and because I was amused about ‘Linq to Reflection’ ;)

private static IEnumerable<string> GetManagementTypes(Assembly a)
{
    string baseType = “Microsoft.Web.Management.Server.ConfigurationModuleProvider”;
   
    var types = from t in a.GetExportedTypes()
                where t.BaseType.FullName == baseType
                select t.FullName;

    return types;
}

 

IisRegMgmt01.zip (18.66 KB)

 

This entry was posted in Uncategorized. Bookmark the permalink.

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 )

Facebook photo

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

Connecting to %s