4

how to get the application pool name for a specific website IIS 6 programmatic using C#

EDIT: I already used the methods of DirectoryServices namespace but the application pool name isn't retrieved correctly unless it was explicitly set by using the same code. Which means if u add a website manually using the iis manager and set an application pool, those codes won't work (it will always return DefaultAppPool) more over when I create an application using sharepoint and set a different appPool those methods dont work.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Amr Elsehemy
  • 1,033
  • 4
  • 13
  • 24

3 Answers3

7

I don't agree with you. I coded up a test app and I get the correct AppPool name from it, even if I set the AppPool manually using IIS Manager.

To make sure, I have tested once, name name was ok; then, I popep up the IIS Manager, changed the AppPool, executed iisreset, and ran the test app again - the AppPool name I got was correct again. I don't how your code looked like, but mine is like this:

using System;
using System.IO;
using System.DirectoryServices;

class Class
{
    static void Main(string[] args)
    {
        DirectoryEntry entry = FindVirtualDirectory("<Server>", "Default Web Site", "<WantedVirtualDir>");
        if (entry != null)
        {
            Console.WriteLine(entry.Properties["AppPoolId"].Value);
        }
    }

    static DirectoryEntry FindVirtualDirectory(string server, string website, string virtualdir)
    {
        DirectoryEntry siteEntry = null;
        DirectoryEntry rootEntry = null;
        try
        {
            siteEntry = FindWebSite(server, website);
            if (siteEntry == null)
            {
                return null;
            }

            rootEntry = siteEntry.Children.Find("ROOT", "IIsWebVirtualDir");
            if (rootEntry == null)
            {
                return null;

            }

            return rootEntry.Children.Find(virtualdir, "IIsWebVirtualDir");
        }
        catch (DirectoryNotFoundException ex)
        {
            return null;
        }
        finally
        {
            if (siteEntry != null) siteEntry.Dispose();
            if (rootEntry != null) rootEntry.Dispose();
        }
    }

    static DirectoryEntry FindWebSite(string server, string friendlyName)
    {
        string path = String.Format("IIS://{0}/W3SVC", server);

        using (DirectoryEntry w3svc = new DirectoryEntry(path))
        {
            foreach (DirectoryEntry entry in w3svc.Children)
            {
                if (entry.SchemaClassName == "IIsWebServer" &&
                    entry.Properties["ServerComment"].Value.Equals(friendlyName))
                {
                    return entry;
                }
            }
        }
        return null;
    }
}

Sorry for my lousy english.
Hope I've helped.

Ricardo Nolde
  • 33,390
  • 4
  • 36
  • 40
  • 1
    Nice one, works for IIS7 as well as IIS6. Bear in mind that you won't necessarily need to identify the AppPool for a virtual directory if your service runs under the same identity as the root level throughout. Also, I'm not sure about passing nulls back if the Web site is not found: I'd rather let the system throw. – Jeremy McGee May 20 '10 at 11:00
  • Good to know that it works for IIS7 also! And about the "catch", I agree - you should do what suits you best! – Ricardo Nolde May 20 '10 at 17:14
  • 1
    According to the comment http://stackoverflow.com/q/249927/496357#comment11785064_496357 you may need to enable "IIS 6 WMI Compatibility" on IIS7 for it to work. – Ricardo Nolde Mar 19 '12 at 16:40
1

The classes in the System.DirectoryServices namespace will help you get that information.

Check this article by Rick Strahl for an example:

/// <summary>
/// Returns a list of all the Application Pools configured
/// </summary>
/// <returns></returns>
public ApplicationPool[] GetApplicationPools()
{           
    if (ServerType != WebServerTypes.IIS6 && ServerType != WebServerTypes.IIS7)
        return null;

    DirectoryEntry root = this.GetDirectoryEntry("IIS://" + this.DomainName + "/W3SVC/AppPools");
      if (root == null)
            return null;

    List<ApplicationPool> Pools = new List<ApplicationPool>();

    foreach (DirectoryEntry Entry in root.Children)
    {
        PropertyCollection Properties = Entry.Properties;

        ApplicationPool Pool = new ApplicationPool();
        Pool.Name = Entry.Name;

        Pools.Add(Pool);
    }

    return Pools.ToArray();
}

/// <summary>
/// Create a new Application Pool and return an instance of the entry
/// </summary>
/// <param name="AppPoolName"></param>
/// <returns></returns>
public DirectoryEntry CreateApplicationPool(string AppPoolName)
{
    if (this.ServerType != WebServerTypes.IIS6 && this.ServerType != WebServerTypes.IIS7)
        return null;

    DirectoryEntry root = this.GetDirectoryEntry("IIS://" + this.DomainName + "/W3SVC/AppPools");
    if (root == null)
        return null;

    DirectoryEntry AppPool = root.Invoke("Create", "IIsApplicationPool", AppPoolName) as DirectoryEntry;           
    AppPool.CommitChanges();

    return AppPool;
}

/// <summary>
/// Returns an instance of an Application Pool
/// </summary>
/// <param name="AppPoolName"></param>
/// <returns></returns>
public DirectoryEntry GetApplicationPool(string AppPoolName)
{
    DirectoryEntry root = this.GetDirectoryEntry("IIS://" + this.DomainName + "/W3SVC/AppPools/" + AppPoolName);
    return root;
}

/// <summary>
/// Retrieves an Adsi Node by its path. Abstracted for error handling
/// </summary>
/// <param name="Path">the ADSI path to retrieve: IIS://localhost/w3svc/root</param>
/// <returns>node or null</returns>
private DirectoryEntry GetDirectoryEntry(string Path)
{

    DirectoryEntry root = null;
    try
    {
        root = new DirectoryEntry(Path);
    }
    catch
    {
        this.SetError("Couldn't access node");
        return null;
    }
    if (root == null)
    {
        this.SetError("Couldn't access node");
        return null;
    }
    return root;
}
Ricardo Nolde
  • 33,390
  • 4
  • 36
  • 40
M4N
  • 94,805
  • 45
  • 217
  • 260
  • I already use those methods but the application pool name isn't retrieved correctly unless it was explicitly set by using the same code. Which means if u add a website manually using the iis manager and set an application pool, those codes won't work (it will always return DefaultAppPool) – Amr Elsehemy Feb 04 '09 at 13:30
  • more over when I create an application using sharepoint and set a different appPool those methods dont work. – Amr Elsehemy Feb 04 '09 at 13:30
  • Thanks, I didn't know that. Maybe you should add that information to your question? – M4N Feb 04 '09 at 13:36
1

In brief, there's 2 ways of doing this that spring to mind.

The less sophisticated way is knowing that, IIS6's settings are stored in the MetaBase which is just an Xml file:

C:\WINDOWS\system32\inetsrv\MetaBase.xml

You can just use Linq2Xml and parse the Xml looking for the sites name or Id, The AppPoolId attribute contains the name of the AppPool

The proper way is to use System.DirectoryServices

danswain
  • 4,171
  • 5
  • 37
  • 43