Team blog of MCS @ Middle East and Africa

This blog is created by Microsoft MEA HQ near shoring team, and it aims to share knowledge with the IT community.With its infrastructure and development sides,It brings to you the proven best practices and real world experiences from Subject Matter Experts
Follow Us On Twitter! Subscribe To Our Blog! Contact Us

Writing an IIS 7.5 Auto Start Provider

Writing an IIS 7.5 Auto Start Provider

  • Comments 1
  • Likes

In IIS 7.5 there is a new feature called the auto start provider. This feature allows you to load any custom web application resources to allow the application to provide better performance right from the first request.

 

Usually implementing an auto start provider is a simple task but what I think needs more clarification is how to write a setup module to configure it using code. So I will first start by implementing a custom auto start provider by implementing the interface “IProcessHostPreloadClient”. This interface has only one method as follows.

    public class CustomAutoStartProvider : IProcessHostPreloadClient

    {

        public void PreloadThread(Object obj)

        {

            // Load your custom resources here

        }

        public void Preload(string[] parameters)

        {

            ThreadPool.QueueUserWorkItem(new WaitCallback(PreloadThread), null);

        }

    }

It is not required to start a new loading thread but it is always preferable that you put the extensive loading code in a different thread.

Now to configure this new auto start provider, you need to add its configuration to the ApplicationHost.Config file. You need to perform the following steps:

1-      Register the new auto start in the section “system.applicationHost/serviceAutoStartProviders”.

2-      Change the web application app pool field “startMode” to be “AlwaysRunning”.

3-      Change the web application field “serviceAutoStartEnabled” to be “true”.

4-      Change the web application field “serviceAutoStartProvider” to the name you used when you registered the auto start provider.

Here is how you do it in code.

using (ServerManager serverManager = new ServerManager())

{

    Configuration config = serverManager.GetApplicationHostConfiguration();

    ConfigurationSection serviceAutoStartProvidersSection = config.GetSection("system.applicationHost/serviceAutoStartProviders");

    ConfigurationElementCollection serviceAutoStartProvidersCollection = serviceAutoStartProvidersSection.GetCollection();

    ConfigurationElement addElement = FindElement(serviceAutoStartProvidersCollection, "add", "name", @"CustomAutoStartProvider");

    if (addElement == null)

    {

        addElement = serviceAutoStartProvidersCollection.CreateElement("add");

        addElement["name"] = @"CustomAutoStartProvider";

        addElement["type"] = @"My.Custom.Providers.CustomAutoStartProvider,My.Custom.Providers";

        serviceAutoStartProvidersCollection.Add(addElement);

    }

    else

    {

        addElement["name"] = @"CustomAutoStartProvider";

        addElement["type"] = @"My.Custom.Providers.CustomAutoStartProvider,My.Custom.Providers";

    }

 

    ConfigurationSection applicationPoolsSection = config.GetSection("system.applicationHost/applicationPools");

    ConfigurationElementCollection applicationPoolsCollection = applicationPoolsSection.GetCollection();

    addElement = FindElement(applicationPoolsCollection, "add", "name", siteName);

    if (addElement == null) throw new InvalidOperationException("Element not found!");

    addElement["startMode"] = @"AlwaysRunning";

 

    ConfigurationSection sitesSection = config.GetSection("system.applicationHost/sites");

    ConfigurationElementCollection sitesCollection = sitesSection.GetCollection();

    ConfigurationElement siteElement = FindElement(sitesCollection, "site", "name", siteName);

    if (siteElement == null) throw new InvalidOperationException("Element not found!");

    ConfigurationElementCollection siteCollection = siteElement.GetCollection();

    ConfigurationElement applicationElement = FindElement(siteCollection, "application", "path", @"/");

    if (applicationElement == null) throw new InvalidOperationException("Element not found!");

    applicationElement["serviceAutoStartEnabled"] = true;

    applicationElement["serviceAutoStartProvider"] = @"CustomAutoStartProvider";

 

    serverManager.CommitChanges();

}

The helper function FindElement code is as below.

private static ConfigurationElement FindElement(ConfigurationElementCollection collection, string elementTagName, params string[] keyValues)

{

    foreach (ConfigurationElement element in collection)

    {

        if (String.Equals(element.ElementTagName, elementTagName, StringComparison.OrdinalIgnoreCase))

        {

            bool matches = true;

 

            for (int i = 0; i < keyValues.Length; i += 2)

            {

                object o = element.GetAttributeValue(keyValues[i]);

                string value = null;

                if (o != null)

                {

                    value = o.ToString();

                }

 

                if (!String.Equals(value, keyValues[i + 1], StringComparison.OrdinalIgnoreCase))

                {

                    matches = false;

                    break;

                }

            }

            if (matches)

            {

                return element;

            }

        }

    }

    return null;

}

 

Have fun coding.

Comments
  • Hi,

    Thanks for this post, it is what I am looking for.  Can you shed some light on when the ServerManager code should be run?  I am running my site with a Shared Hosting Provider, and was hoping to be able to use your code to configure my warmup.  Thanks in advance.

    Regards,

    Andy

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment