Creating Virtual directory in IIS with c#

12,567

Solution 1

This is the code my application uses that references the System.DirectoryServices dll:

    using System.DirectoryServices;
    using System.IO;
    /// <summary>
    /// Creates the virtual directory.
    /// </summary>
    /// <param name="webSite">The web site.</param>
    /// <param name="appName">Name of the app.</param>
    /// <param name="path">The path.</param>
    /// <returns></returns>
    /// <exception cref="Exception"><c>Exception</c>.</exception>
    public static bool CreateVirtualDirectory(string webSite, string appName, string path)
    {
        var schema = new DirectoryEntry("IIS://" + webSite + "/Schema/AppIsolated");
        bool canCreate = !(schema.Properties["Syntax"].Value.ToString().ToUpper() == "BOOLEAN");
        schema.Dispose();

        if (canCreate)
        {
            bool pathCreated = false;
            try
            {
                var admin = new DirectoryEntry("IIS://" + webSite + "/W3SVC/1/Root");

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

                //If the virtual directory already exists then delete it
                IEnumerable<DirectoryEntry> matchingEntries = admin.Children.Cast<DirectoryEntry>().Where(v => v.Name == appName);
                foreach (DirectoryEntry vd in matchingEntries)
                {
                    admin.Invoke("Delete", new[] { vd.SchemaClassName, appName }); 
                    admin.CommitChanges();
                    break;
                }

                //Create and setup new virtual directory
                DirectoryEntry vdir = admin.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.aspx,default.asp,default.htm";
                vdir.Properties["AspEnableParentPaths"][0] = true;
                vdir.CommitChanges();

                //the following are acceptable params
                //INPROC = 0, OUTPROC = 1, POOLED = 2
                vdir.Invoke("AppCreate", 1);

                return true;
            }
            catch (Exception)
            {
                if (pathCreated)
                    Directory.Delete(path);
                throw;
            }
        }
        return false;
    }

Solution 2

This may be a bit of a stretch since it's not C# or MSBuild, but how about using a simple vbscript to do it?

http://msdn.microsoft.com/en-us/library/ms951564.aspx#autoadm_topic5

This could be configured in an MSBuild task.

Solution 3

What about using the same approach suggested by Dylan, but directly in C#?

See: Creating Sites and Virtual Directories Using System.DirectoryServices for a starting point.

Share:
12,567
Lodewijk
Author by

Lodewijk

Hi!

Updated on June 28, 2022

Comments

  • Lodewijk
    Lodewijk almost 2 years

    This one will need a bit of explanation...

    I want to set up IIS automagically so our Integration tests (using Watin) can run on any environment. To that end I want to create a Setup and Teardown that will create and destroy a virtual directory respectively.

    The solution I thought of was to use the MSBuild Community Tasks to automate IIS in code with a mocked IBuildEngine.

    However, when I try to create a virtual directory, I get the following error code: 0x80005008. Edit: I removed artifacts from earlier attemps, and now I get an IndexOutOfRangeException

    I'm on Vista with IIS7. This is the code I'm using to run the task:

    var buildEngine = new MockedBuildEngine();
    buildEngine.OnError += (o, e) => Console.WriteLine("ERROR" + e.Message);
    buildEngine.OnMessage += (o, e) => Console.WriteLine("MESSAGE" + e.Message);
    buildEngine.OnWarning += (o, e) => Console.WriteLine("WARNING: " + e.Message);
    
    var createWebsite = new MSBuild.Community.Tasks.IIS.WebDirectoryCreate()
                        {
                            ServerName = "localhost",
                            VirtualDirectoryPhysicalPath = websiteFolder.FullName,
                            VirtualDirectoryName = "MedicatiebeheerFittests",
                            AccessRead = true,
                            AuthAnonymous = true,
                            AnonymousPasswordSync = false,
                            AuthNtlm = true,
                            EnableDefaultDoc = true,
                            BuildEngine = buildEngine
                        };
    
    createWebsite.Execute();
    

    Somebody knows what is going on here? Or does someone know a better way of doing this?

  • Lodewijk
    Lodewijk almost 15 years
    I would need to initialize the vbscript from within c# in my scenario. Not pretty, but it could work...
  • Dylan
    Dylan almost 15 years
    Which is essentially how the MSBuild folks do it. There's another example of this here: stackoverflow.com/questions/266026/… (look at the answer that says NOT TESTED). Funnily enough another suggestion on that answer is to use WiX. I use the WiX IIS functions in a couple of installers I've written, and again it's open source so you could take a look there. But I'd probably just start with the answer I've mentioned.
  • Lodewijk
    Lodewijk almost 15 years
    Thanks for the msdn links. They'll be very helpfull!
  • Rui Caramalho
    Rui Caramalho almost 4 years
    What adaption is necessary for doing the same in another IIS on our LAN server. Assuming the current impersonation user already has permission?
  • neontapir
    neontapir almost 4 years
    I'm sorry, I don't know offhand.