1

I have a web application that deploys with two virtual directories under it's IIS virtual application. On IIS 6 boxes, the following code creates these virtual directories as expected, however on IIS 7 boxes, I end up with my virtual application having two other virtual applications under it, rather than one virtual application with two virtual directories under it. I've tried the following two methods, but both still create a virtual application, not a virtual directory. How can this code be changed to deploy the needed virtual directories, not the undesired virtual applications?

one:

private void AddVirtualDir(DirectoryEntry entry)
{
    DirectoryEntry virtualDirectory = (DirectoryEntry)entry.Invoke("Create", "IIsWebVirtualDir", "VirtualDirectory");
    virtualDirectory.InvokeSet("Path", @"VirtualPath");
    virtualDirectory.InvokeSet("AppFriendlyName", "VirtualDirectory");
    virtualDirectory.Properties["AccessRead"][0] = true;
    virtualDirectory.Properties["AccessScript"][0] = 512;
    virtualDirectory.Properties["AppIsolated"].Clear();
    virtualDirectory.Properties["AppIsolated"].Add(2);
    virtualDirectory.Invoke("AppCreate", false);
    virtualDirectory.CommitChanges();
    entry.CommitChanges();
}

two:

private void AddVirtualDir(DirectoryEntry entry)
{
    var virtualDirectory = entry.Children.Add("VirtualDirectory", "IIsWebVirtualDir");
    virtualDirectory.Properties["AccessRead"][0] = true;
    virtualDirectory.Properties["AccessScript"][0] = 512;
    virtualDirectory.Properties["AppFriendlyName"][0] = "EditorControls";
    virtualDirectory.Properties["AppIsolated"][0] = 2;
    virtualDirectory.Properties["Path"][0] = Path.Combine(_INSTALLDIR, @"Kryptiq_Root\FormManagement\EditorControls");
    virtualDirectory.CommitChanges();
    entry.CommitChanges();
}
svick
  • 236,525
  • 50
  • 385
  • 514
Jon Ediger
  • 949
  • 1
  • 10
  • 27
  • Can you post a screenshot of what this looks like in IIS6 (remember to expand all the necessary nodes), I'm having trouble working out what this should look like. Also the two examples given, are these two different things you tried? – Kev Jan 27 '12 at 03:38
  • Yes, the two different things are two different ways I tried. Your suggestion works great on IIS 7. At the moment, it seems like IIS 6 isn't getting the asp.net extensions set, which I am investigating. – Jon Ediger Jan 27 '12 at 23:33
  • On talking with QA, the current IIS 6 issue doesn't seem to involve the virtual directories of this change. The whole virtual app that gets created doesn't have the .net extensions. I'm investigating the other code changes to my config file unrelated to this change. – Jon Ediger Jan 28 '12 at 00:49

1 Answers1

2

How this works on IIS6

The problem here is that you're setting the AppIsolated value. In IIS6 this is used to configure how an application should run, and generally you should never need to touch this or add it anywhere.

AppIsolated always defaults to 2 which means pooled process, i.e. the application will run in either the parent application's application pool or in the pool specified by AppPoolId.

The reason that there are other values is so that you can configure an application to run in a couple of legacy IIS5 modes - In Process and Out of Process mode.

So unless you configured your site's /root application to run as anything other than AppIsolated="2" then you don't need to set this value.

Your code can be as simple as:

using (var entry = new DirectoryEntry("IIS://localhost/W3SVC/1/ROOT"))
{
  using (DirectoryEntry virtualDirectory = entry.Children.Add("MyVdir", 
                                           "IIsWebVirtualDir"))
  {
    virtualDirectory.Properties["Path"][0] = PATH_TO_MY_STUFF;
    virtualDirectory.Properties["AccessRead"][0] = true;
    virtualDirectory.Properties["AccessScript"][0] = 512;
    virtualDirectory.CommitChanges();
  }
}

If you do set AppIsolated in IIS6 it gets ignored because for the directory to become an application you also need to set AppRoot.

IIS7 - IIS6 compatibility shim

In IIS7 when using System.DirectoryServices you're working with an underlying II6 compatibility API which is translating these ADSI calls to calls to the new IIS7 API. It's not perfect and I suspect that when it see's AppIsolated being set it's assuming you want an application, despite you not specifying any other application related metabase values.

IIS7 Managed API is better

You probably know this, but it's better to work with IIS7 configuration via the managed Microsoft.Web.Administration bits. Not all of the ADSI/metabase compatibility settings have equivalents in IIS7 which can force the translation layer to make compromises to work around this. I mention these types of problems in my answers here and here.

Community
  • 1
  • 1
Kev
  • 118,037
  • 53
  • 300
  • 385