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);
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, "IIsWebVirtualDir"); 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); } }
The limitation is that the virtual directory can only be created under a Server or VirtualDir object. My IIS has the following structure:
[site]/[vdir]/[subfolder]
Where [site] is an iis site, [vdir] is a virtual directory and [subfolder] is a folder that resides under the physical folder that is pointed to by [vdir]. Now, I can successfully create a new virtual directory under [vdir], but what I want to do is create one under [subfolder].
I can do this manually within IIS but not programmatically. The SchemaClassName reported by DirectoryEntry for [subfolder] is IIsObject, so the above code in it's original form (correctly) falls to the else branch. If I modify the if statement and attempt to create the virtual directory under [subfolder] I get a HRESULT: 0x8000500F exception.
So, if I can create a virtual directory manually in IIS at this location, even though the SchemaClassName is not strictly a VirtualDir, why cant I do it programmatically using DirectoryEntry methods? Is there a workaround for this? Can I "cast" the SchemaClassName of IIsObject to IIsWebVirtualDir? Any other hints or tips?
> successfully creates a virtual directory at a specific location.
> 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);
> 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, > "IIsWebVirtualDir"); > 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); > } > }
> The limitation is that the virtual directory can only be created under > a Server or VirtualDir object. My IIS has the following structure:
> [site]/[vdir]/[subfolder]
> Where [site] is an iis site, [vdir] is a virtual directory and > [subfolder] is a folder that resides under the physical folder that is > pointed to by [vdir]. Now, I can successfully create a new virtual > directory under [vdir], but what I want to do is create one under > [subfolder].
> I can do this manually within IIS but not programmatically. The > SchemaClassName reported by DirectoryEntry for [subfolder] is > IIsObject, so the above code in it's original form (correctly) falls > to the else branch. If I modify the if statement and attempt to > create the virtual directory under [subfolder] I get a HRESULT: > 0x8000500F exception.
> this means "E_ADS_SCHEMA_VIOLATION - The attempted action violates the > directory service schema rules".
> So, if I can create a virtual directory manually in IIS at this > location, even though the SchemaClassName is not strictly a > VirtualDir, why cant I do it programmatically using DirectoryEntry > methods? Is there a workaround for this? Can I "cast" the > SchemaClassName of IIsObject to IIsWebVirtualDir? Any other hints or > tips?
I would suggest two things: Repost on microsoft.public.platformsdk.adsi.iis-admin Consider using WMI (System.Management) for modifying IIS instead of ADSI/SDS
There are some known bugs in the SDS implementation which cause problems with the IIS provider. I think a lot of these have been resolved in .NET 2.0, but that might not help you. I'm also not an expert, so I have no idea if this is the issue or not, but it is something to think about.
>> 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);
>> 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, >> "IIsWebVirtualDir"); >> 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); >> } >> }
>> The limitation is that the virtual directory can only be created > under >> a Server or VirtualDir object. My IIS has the following structure:
>> [site]/[vdir]/[subfolder]
>> Where [site] is an iis site, [vdir] is a virtual directory and >> [subfolder] is a folder that resides under the physical folder that > is >> pointed to by [vdir]. Now, I can successfully create a new virtual >> directory under [vdir], but what I want to do is create one under >> [subfolder].
>> I can do this manually within IIS but not programmatically. The >> SchemaClassName reported by DirectoryEntry for [subfolder] is >> IIsObject, so the above code in it's original form (correctly) falls >> to the else branch. If I modify the if statement and attempt to >> create the virtual directory under [subfolder] I get a HRESULT: >> 0x8000500F exception.
>> So, if I can create a virtual directory manually in IIS at this >> location, even though the SchemaClassName is not strictly a >> VirtualDir, why cant I do it programmatically using DirectoryEntry >> methods? Is there a workaround for this? Can I "cast" the >> SchemaClassName of IIsObject to IIsWebVirtualDir? Any other hints or >> tips?
> I would suggest two things: > Repost on microsoft.public.platformsdk.adsi.iis-admin > Consider using WMI (System.Management) for modifying IIS instead of > ADSI/SDS
> There are some known bugs in the SDS implementation which cause problems > with the IIS provider. I think a lot of these have been resolved in .NET > 2.0, but that might not help you. I'm also not an expert, so I have no > idea if this is the issue or not, but it is something to think about.
>>> 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);
>>> 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, >>> "IIsWebVirtualDir"); >>> 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); >>> } >>> }
>>> The limitation is that the virtual directory can only be created >> under >>> a Server or VirtualDir object. My IIS has the following structure:
>>> [site]/[vdir]/[subfolder]
>>> Where [site] is an iis site, [vdir] is a virtual directory and >>> [subfolder] is a folder that resides under the physical folder that >> is >>> pointed to by [vdir]. Now, I can successfully create a new virtual >>> directory under [vdir], but what I want to do is create one under >>> [subfolder].
>>> I can do this manually within IIS but not programmatically. The >>> SchemaClassName reported by DirectoryEntry for [subfolder] is >>> IIsObject, so the above code in it's original form (correctly) falls >>> to the else branch. If I modify the if statement and attempt to >>> create the virtual directory under [subfolder] I get a HRESULT: >>> 0x8000500F exception.
>>> So, if I can create a virtual directory manually in IIS at this >>> location, even though the SchemaClassName is not strictly a >>> VirtualDir, why cant I do it programmatically using DirectoryEntry >>> methods? Is there a workaround for this? Can I "cast" the >>> SchemaClassName of IIsObject to IIsWebVirtualDir? Any other hints or >>> tips?
I have re-posted on the newsgroup you mentioned and will investigate your WMI suggestion. I'll post a follow-up to this thread if any breakthroughs materialise.
> > I would suggest two things: > > Repost on microsoft.public.platformsdk.adsi.iis-admin > > Consider using WMI (System.Management) for modifying IIS instead of > > ADSI/SDS
> > There are some known bugs in the SDS implementation which cause problems > > with the IIS provider. I think a lot of these have been resolved in .NET > > 2.0, but that might not help you. I'm also not an expert, so I have no > > idea if this is the issue or not, but it is something to think about.
> >>> 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);
> >>> 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, > >>> "IIsWebVirtualDir"); > >>> 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); > >>> } > >>> }
> >>> The limitation is that the virtual directory can only be created > >> under > >>> a Server or VirtualDir object. My IIS has the following structure:
> >>> [site]/[vdir]/[subfolder]
> >>> Where [site] is an iis site, [vdir] is a virtual directory and > >>> [subfolder] is a folder that resides under the physical folder that > >> is > >>> pointed to by [vdir]. Now, I can successfully create a new virtual > >>> directory under [vdir], but what I want to do is create one under > >>> [subfolder].
> >>> I can do this manually within IIS but not programmatically. The > >>> SchemaClassName reported by DirectoryEntry for [subfolder] is > >>> IIsObject, so the above code in it's original form (correctly) falls > >>> to the else branch. If I modify the if statement and attempt to > >>> create the virtual directory under [subfolder] I get a HRESULT: > >>> 0x8000500F exception.
> >>> So, if I can create a virtual directory manually in IIS at this > >>> location, even though the SchemaClassName is not strictly a > >>> VirtualDir, why cant I do it programmatically using DirectoryEntry > >>> methods? Is there a workaround for this? Can I "cast" the > >>> SchemaClassName of IIsObject to IIsWebVirtualDir? Any other hints or > >>> tips?
No breakthroughs yet, but curiously I discovered that the DirectoryEntry object is able to remove the virtual directory from my desired location if I create it there manually - but it just won't create it under an IIsObject node. This strongly suggests a bug in the DirectoryEntry.Add method. Can anyone from Microsoft confirm this? Better yet, is there a workaround?
> I have re-posted on the newsgroup you mentioned and will investigate > your WMI suggestion. I'll post a follow-up to this thread if any > breakthroughs materialise.
> > > I would suggest two things: > > > Repost on microsoft.public.platformsdk.adsi.iis-admin > > > Consider using WMI (System.Management) for modifying IIS instead of > > > ADSI/SDS
> > > There are some known bugs in the SDS implementation which cause problems > > > with the IIS provider. I think a lot of these have been resolved in .NET > > > 2.0, but that might not help you. I'm also not an expert, so I have no > > > idea if this is the issue or not, but it is something to think about.
> > >>> 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);
> > >>> 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); > > >>> } > > >>> }
> > >>> The limitation is that the virtual directory can only be created > > >> under > > >>> a Server or VirtualDir object. My IIS has the following structure:
> > >>> [site]/[vdir]/[subfolder]
> > >>> Where [site] is an iis site, [vdir] is a virtual directory and > > >>> [subfolder] is a folder that resides under the physical folder that > > >> is > > >>> pointed to by [vdir]. Now, I can successfully create a new virtual > > >>> directory under [vdir], but what I want to do is create one under > > >>> [subfolder].
> > >>> I can do this manually within IIS but not programmatically. The > > >>> SchemaClassName reported by DirectoryEntry for [subfolder] is > > >>> IIsObject, so the above code in it's original form (correctly) falls > > >>> to the else branch. If I modify the if statement and attempt to > > >>> create the virtual directory under [subfolder] I get a HRESULT: > > >>> 0x8000500F exception.
> > >>> So, if I can create a virtual directory manually in IIS at this > > >>> location, even though the SchemaClassName is not strictly a > > >>> VirtualDir, why cant I do it programmatically using DirectoryEntry > > >>> methods? Is there a workaround for this? Can I "cast" the > > >>> SchemaClassName of IIsObject to IIsWebVirtualDir? Any other hints or > > >>> tips?