Create a virtual directory in IIS using ASP.NET and C#

Update 30th July 2009: After deploying this to a development server there were a few tweaks I needed to make to get it working. I  have amended the post as necessary.

I needed to be able to create a virtual directory in IIS via my ASP.NET application.  I found this nice little example in VB.NET and converted it to C#.  You need to add a reference to System.DirectoryServices to use it.  The VB.NET example always puts the new virtual directory in the default website, so I have amended it to allow choosing the server and website you want to place the virtual directory under.


private void CreateVirtualDir(string serverName, string website, string appName, string path)
{
    DirectoryEntry IISSchema = new DirectoryEntry(string.Concat("IIS://", serverName, "/Schema/AppIsolated"));
    bool canCreate = IISSchema.Properties["Syntax"].Value.ToString().ToUpper() != "BOOLEAN";
    IISSchema.Dispose();

    //get the identifier for the site we want
    int identifier = 0;
    DirectoryEntry root = new DirectoryEntry(string.Concat("IIS://", serverName, "/W3SVC"));
    foreach(DirectoryEntry de in root.Children)
    {
        if (de.SchemaClassName.ToUpper().Equals("IISWEBSERVER") &&
            de.Invoke("Get", "ServerComment").ToString().ToUpper().Equals(website.ToUpper()))
        {
            identifier = Convert.ToInt32(de.Name);
            break;
        }
    }

    if (canCreate && identifier > 0)
    {
        bool pathCreated = false;
        try
        {
            DirectoryEntry iisAdmin = new DirectoryEntry(string.Format("IIS://{0}/W3SVC/{1}/Root", serverName, identifier));

            //make sure folder exists
            if (!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
                pathCreated = true;
            }

            //If the virtual directory already exists then delete it
            foreach (DirectoryEntry vd in iisAdmin.Children)
            {
                if (vd.Name.Equals(appName))
                {
                    iisAdmin.Invoke("Delete", new string[] { vd.SchemaClassName, appName });
                    iisAdmin.CommitChanges();
                    break;
                }
            }

            //Create and setup new virtual directory
            DirectoryEntry vDir = iisAdmin.Children.Add(appName, "IIsWebVirtualDir");
            vDir.Properties["Path"][0] = path;
            vDir.Properties["AppFriendlyName"][0] = appName;
            vDir.Properties["EnableDirBrowsing"][0] = false;
            vDir.Properties["AccessRead"][0] = true;
            vDir.Properties["AccessExecute"][0] = true;
            vDir.Properties["AccessWrite"][0] = false;
            vDir.Properties["AccessScript"][0] = true;
            vDir.Properties["AuthNTLM"][0] = true;
            vDir.Properties["EnableDefaultDoc"][0] = true;
            vDir.Properties["DefaultDoc"][0] = "default.htm,default.aspx,default.asp";
            vDir.Properties["AspEnableParentPaths"][0] = true;
            vDir.CommitChanges();

            //the following are acceptable params
            //INPROC = 0
            //OUTPROC = 1
            //POOLED = 2
            vDir.Invoke("AppCreate", 1);
        }
        catch (Exception ex)
        {
            if (pathCreated)
            {
                System.IO.Directory.Delete(path);
            }

            throw ex;
        }
    }
    else
    {
        throw new ApplicationException("Failed to create Virtual Directory");
    }
}

To create a new virtual directory I can then call the method like this:

try
{
    CreateVirtualDir("localhost", "MyWebSite" "MyVirtualDirectory", @"c:\sites\mysite");
}
catch (Exception ex)
{
    lblMessage.Text = string.Concat("An error occurred: ", ex.Message);
}

When I deployed this to a development server I got an ‘Access is denied’ error on this following line:

vDir.CommitChanges();

This is because IIS administration need to be done by a user in the administrator group which is the ASPNET user is not.  To resolve this I created a new window user on the server which was a member of the administrator group.  I then added the following to my Web.config:

<system.web>
    <identity impersonate="true" userName="username" password="password" />
</system.web>

You could also wrap this in an pages element to restrict which pages will impersonate this identity.

Posted on by Joe in ASP.NET, C#

Add a Comment