9
votes

As part of starting up a WebRole on Windows Azure I would like to access files on the website being started and I would like to do this in RoleEntryPoint.OnStart(). This will for instance enable me to influence ASP.NET config before the ASP.NET AppDomain is loaded.

When running locally with Azure SDK 1.3 and VS2010 the sample code below do the trick, but the code has the stench of hack around it and it does not do the trick when deploying to Azure.

  XNamespace srvDefNs = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition";
  DirectoryInfo di = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
  string roleRoot = di.Parent.Parent.FullName;
  XDocument roleModel = XDocument.Load(Path.Combine(roleRoot, "RoleModel.xml"));
  var propertyElements = roleModel.Descendants(srvDefNs + "Property");
  XElement sitePhysicalPathPropertyElement = propertyElements.Attributes("name").Where(nameAttr => nameAttr.Value == "SitePhysicalPath").Single().Parent;
  string pathToWebsite = sitePhysicalPathPropertyElement.Attribute("value").Value;

How can I get the WebRole site root path from RoleEntryPoint.OnStart() in a way that work in both dev and on Azure?

2

2 Answers

12
votes

This seem to work in both dev and on Windows Azure:

private IEnumerable<string> WebSiteDirectories
{
    get
    {
        string roleRootDir = Environment.GetEnvironmentVariable("RdRoleRoot");
        string appRootDir = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);

        XDocument roleModelDoc = XDocument.Load(Path.Combine(roleRootDir, "RoleModel.xml"));
        var siteElements = roleModelDoc.Root.Element(_roleModelNs + "Sites").Elements(_roleModelNs + "Site");

        return
            from siteElement in siteElements
            where siteElement.Attribute("name") != null
                    && siteElement.Attribute("name").Value == "Web"
                    && siteElement.Attribute("physicalDirectory") != null
            select Path.Combine(appRootDir, siteElement.Attribute("physicalDirectory").Value);
    }
}

If anyone use this to manipulate files in the ASP.NET app, you should know that the files written by RoleEntryPoint.OnStart() will have ACL settings that prevent the ASP.NET application from updating them.

If you need to write to such files from ASP.NET this code show how you can change file permissions so this is possible:

SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
IdentityReference act = sid.Translate(typeof(NTAccount));
FileSecurity sec = File.GetAccessControl(testFilePath);
sec.AddAccessRule(new FileSystemAccessRule(act, FileSystemRights.FullControl, AccessControlType.Allow));
File.SetAccessControl(testFilePath, sec);
4
votes

Take a look at:

Environment.GetEnvironmentVariable("RoleRoot")

Does that give you what you're looking for?