[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 502
  • Last Modified:

Creating Website Dynamically IIS 7

Hi all,

I am creating websites dynamically in IIS, before I do this I have a 'does website exist' check.

    public static bool DoesWebsiteExist(string websiteName)
    {
        bool result = false;

        DirectoryEntry w3svc = new DirectoryEntry("IIS://localhost/w3svc", iis_login, iis_password);

        foreach (DirectoryEntry site in w3svc.Children)
        {
            if (site.Properties["ServerComment"] != null)
            {
                if (site.Properties["ServerComment"].Value != null)
                {
                    if (string.Compare(site.Properties["ServerComment"].Value.ToString(), websiteName, false) == 0)
                    {
                        result = true;
                    }
                }
            }
        }

        return result;
    }

Open in new window


however, I am getting an Access is Denied error from the DirectoryEntry.

Now the iis_user and iis_password are a user/password combination for a user in IIS Manage Users.

Any ideas what I am doing wrong here?
0
flynny
Asked:
flynny
  • 10
  • 9
1 Solution
 
Utkarsh KulkarniCommented:
It seems, your application does not has rights to create directory in IIS (i.e. creating directory in c:/inetpub/wwwroot/...).

Give proper permissions to this folder. Also, is your application is web or windows ?
Web Application does not have this permission by default for security reasons.
0
 
flynnyAuthor Commented:
ok what user should i give writing rights to?

i.e. will it be IIS_USERS?
0
 
Utkarsh KulkarniCommented:
If your application is windows application, then you need to give permission for Trusted installer / admin user etc.
If its web application, then give it to IIS_USERs.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
flynnyAuthor Commented:
ok after adding the permissions for IIS_USERS and debugging on the following line

DirectoryEntry w3svc = new DirectoryEntry("IIS://localhost/w3svc");

        foreach (DirectoryEntry site in w3svc.Children)

Open in new window


it is throwing the following error;

Error: Unknown error (0x80005000)

any ideas?
0
 
Utkarsh KulkarniCommented:
Need to look thorough. Is it web application or windows application ?
0
 
flynnyAuthor Commented:
its a web application running on IIS7 and is running on the same server I am trying to create the site on.
0
 
Utkarsh KulkarniCommented:
I will suggest couple of changes

1. Make the Identity of the application pool for this site (using which you are trying to create new site) to "Local System" (Note - This is highest privileged account)
2. Give full control to "Trusted installer" user/user group. (Ref - Permission for "wwwroot" folder)
0
 
flynnyAuthor Commented:
Apologies for my delay in coming back to you.

Point 1 has solved the issue and it now runs smoothly. However the sites are not appearing in IIS?

The directory is create, the application pool is create and I can see this in IIS. However whilst the code runs it is not appearing in IIS??
    static void CreateVDir(string metabasePath, string vDirName, string physicalPath)
    {
        //  metabasePath is of the form "IIS://<servername>/<service>/<siteID>/Root[/<vdir>]"
        //    for example "IIS://localhost/W3SVC/1/Root" 
        //  vDirName is of the form "<name>", for example, "MyNewVDir"
        //  physicalPath is of the form "<drive>:\<path>", for example, "C:\Inetpub\Wwwroot"
        Console.WriteLine("\nCreating virtual directory {0}/{1}, mapping the Root application to {2}:",
            metabasePath, vDirName, physicalPath);

        Global.log.Debug(String.Format("Debug: Creating virtual directory :{0}/{1}: mapping the Root application to :{2}:", metabasePath, vDirName, physicalPath));

        try
        {
            DirectoryEntry site = new DirectoryEntry(metabasePath);
            string className = site.SchemaClassName.ToString();
            if ((className.EndsWith("Server")) || (className.EndsWith("VirtualDir")))
            {
                DirectoryEntries vdirs = site.Children;
                DirectoryEntry newVDir = vdirs.Add(vDirName, (className.Replace("Service", "VirtualDir")));
                newVDir.Properties["Path"][0] = physicalPath;
                newVDir.Properties["AccessScript"][0] = true;
                // These properties are necessary for an application to be created.
                newVDir.Properties["AppFriendlyName"][0] = vDirName;
                newVDir.Properties["AppIsolated"][0] = "1";
                newVDir.Properties["AppRoot"][0] = "/LM" + metabasePath.Substring(metabasePath.IndexOf("/", ("IIS://".Length)));

                newVDir.CommitChanges();

                Console.WriteLine(" Done.");
            }
            else
                Console.WriteLine(" Failed. A virtual directory can only be created in a site or virtual directory node.");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Failed in CreateVDir with the following exception: \n{0}", ex.Message);
        }
    }

Open in new window



Here is the print out from the logging
2014-05-06 14:25:32,702 [9] DEBUG Global - Debug: ABOUT TO CHECK WEBSITE EXISTS!
2014-05-06 14:25:33,130 [9] DEBUG Global - Debug: Does Website Exist? False
2014-05-06 14:25:33,440 [9] DEBUG Global - Debug: Website does not exist!
2014-05-06 14:25:33,441 [9] DEBUG Global - Debug: Website directory is :C:\Inetpub\Wwwroot\Sites\BIGBANG:
2014-05-06 14:25:33,443 [9] DEBUG Global - Debug: Creating application pool named :IIS://Localhost/W3SVC/AppPools/BIGBANG:
2014-05-06 14:25:33,709 [9] DEBUG Global - Debug: Creating virtual directory :IIS://Localhost/W3SVC/1/Root//BIGBANG: mapping the Root application to :C:\Inetpub\Wwwroot\Sites\BIGBANG:

Open in new window

0
 
Utkarsh KulkarniCommented:
It will not create the website but it creates Virtual directory under root website.
E.g. your default website runs on port 80. So this newly created website is virtual directory hence its url will be like http://localhost:80/<foldername>/
0
 
flynnyAuthor Commented:
apologies after further debuggin its actually throwing this error which i misse dwhen logging

Failed in CreateVDir with the following exception :Unknown error (0x80005000):

Open in new window

0
 
Utkarsh KulkarniCommented:
Is it appearing for all ?
0
 
flynnyAuthor Commented:
Thanks for your reply I really appreciate your help.

ok after further debugging it is throwing the error when it hits this line;

string className = site.SchemaClassName;

Open in new window


(I have tried with and without the redundant .ToString() call).
0
 
Utkarsh KulkarniCommented:
You can add couple of checks like
1. Is site has value for SchemaClassName
2. using Convert.ToString() method

e.g. If site.SchemaClassName.Length() >0 or if site!=null
This might give you an idea.
0
 
flynnyAuthor Commented:
Hi,

thanks for the advice. I have done the following;

            Global.log.Debug(String.Format("Debug: DirectoryEntry :{0}:", site));

            if(site == null)
                Global.log.Debug("Debug: site is NULL");

Open in new window


with the following being output, so it appears 'site' is not null

2014-05-06 16:15:16,347 [25] DEBUG Global - Debug: DirectoryEntry :System.DirectoryServices.DirectoryEntry:

Open in new window

0
 
flynnyAuthor Commented:
ok i change the code tot he following and this is working

        string siteDirectory = "C:\\Inetpub\\Wwwroot\\Sites\\" + subdomain;

        Global.log.Debug(String.Format("Debug: Website directory is :{0}:", siteDirectory));

        ServerManager serverMgr = new ServerManager();
        Site mySite = serverMgr.Sites.Add(subdomain + ".mydom.com", siteDirectory, 8080);
        serverMgr.ApplicationPools.Add(subdomain);
        mySite.ApplicationDefaults.ApplicationPoolName = subdomain;
        mySite.TraceFailedRequestsLogging.Enabled = true;
        mySite.TraceFailedRequestsLogging.Directory = siteDirectory;
        serverMgr.CommitChanges();

       // CreateAppPool("IIS://Localhost/W3SVC/AppPools", subdomain);
       // CreateVDir("IIS://Localhost/W3SVC/1/Root/", subdomain, siteDirectory);
       // AssignVDirToAppPool("IIS://Localhost/W3SVC/1/Root/" + subdomain, subdomain);
        CopySite(defaultSiteDirectory, siteDirectory);

Open in new window


however, how do I add the site bindings to the site? i.e. so that subdomain.mydom.com is the bound domain tot he site?

also how do I change the .net version assigned to the pool?

thanks for all the help.
0
 
Utkarsh KulkarniCommented:
You can use ServerManager class for this

To create an application pool use  Microsoft.Web.Administration and set the .NET Framework version to 4.0, do this:

using Microsoft.Web.Administration;
...

using(ServerManager serverManager = new ServerManager())
{
  ApplicationPool newPool = serverManager.ApplicationPools.Add("MyNewPool");
  newPool.ManagedRuntimeVersion = "v4.0";
  serverManager.CommitChanges();
}

You should add a reference to Microsoft.Web.Administration.dll which can be found in:

%SYSTEMROOT%\System32\InetSrv


As you are using Directory Entry use following

newpool.Properties["ManagedRuntimeVersion"].Value = "v4.0";

newPool.InvokeSet("ManagedPipelineMode", new object[] { 0 });


Entire Reference you can get at

http://patelshailesh.com/index.php/create-a-website-application-pool-programmatically-using-csharp
0
 
flynnyAuthor Commented:
Many thanks for this this is working.

Is it possible to add further bindings to the site, as i mentioned before the site is now setup and appearing in IIS but there are now urls bound to the site?
0
 
Utkarsh KulkarniCommented:
You can add with Properties collection

site.Properties["Serverbindings"].Clear();
site.Properties["Serverbindings"].Add(":" + port + ":");

Else you can loop through Properties collection for exact attribute (and its value) and then right the code for setting it.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 10
  • 9
Tackle projects and never again get stuck behind a technical roadblock.
Join Now