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)
IIS
4/20/2008 6:50:57 AM UTC
|