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();
}
How this works on IIS6
The problem here is that you’re setting the
AppIsolatedvalue. 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.AppIsolatedalways defaults to2which means pooled process, i.e. the application will run in either the parent application’s application pool or in the pool specified byAppPoolId.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
/rootapplication to run as anything other thanAppIsolated="2"then you don’t need to set this value.Your code can be as simple as:
If you do set
AppIsolatedin IIS6 it gets ignored because for the directory to become an application you also need to setAppRoot.IIS7 – IIS6 compatibility shim
In IIS7 when using
System.DirectoryServicesyou’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’sAppIsolatedbeing 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.Administrationbits. 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.