如何确定“IIsWebDirectory”是否已存在 或“IIsWebVirtualDir” 是 ASP.NET 应用程序吗?
我目前正在编写一个 C# asp.net 应用程序来连接到 IIS 服务器并查询虚拟目录/Web 目录信息。
我能够确定我应该处理的两种类型是“IIsWebDirectory”和“IIsWebVirtualDir”。
如何确定它们是否已配置为 C# 中的“应用程序”?
更新
@Kev - 我在您的答案中获取了信息,并开发了以下简单的解决方案来检查 AppFriendlyName 是否未设置为“默认应用程序”
private void CheckIfApp(DirectoryEntry de)
{
if(de.SchemaClassName.Equals("IIsWebDirectory") || de.SchemaClassName.Equals("IIsWebVirtualDir"))
{
if (de.Properties["AppFriendlyName"].Value != null)
{
string friendlyName = de.Properties["AppFriendlyName"].Value.ToString();
if (!friendlyName.Equals("Default Application"))
{
//do something...
}
}
}
}
I am currently writing an C# asp.net application to connect to an IIS server and query the virtual directory/web directory information.
I am able to determine that there are that two types I should be dealing with is an "IIsWebDirectory" and "IIsWebVirtualDir".
How to I determine if they have been configured to be an "application" in C#?
You can also view my adventures in C# and IIS here and here
UPDATE
@Kev - I took the information in your answer and developed the following simple solution to check to see if the AppFriendlyName is not set to "Default Application"
private void CheckIfApp(DirectoryEntry de)
{
if(de.SchemaClassName.Equals("IIsWebDirectory") || de.SchemaClassName.Equals("IIsWebVirtualDir"))
{
if (de.Properties["AppFriendlyName"].Value != null)
{
string friendlyName = de.Properties["AppFriendlyName"].Value.ToString();
if (!friendlyName.Equals("Default Application"))
{
//do something...
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以通过三种方法解决此问题:
interop
普通旧式 System.DirectoryServices
确定
IIsWebDirectory
或IIsWebVirtualDir
IIS 管理对象是否配置为应用程序由于配置数据库属性继承,单独使用 System.DirectoryServices 有时可能不是一件显而易见的事情。例如,当您创建“应用程序”时,通常会在
IIsWebDirectory
或IIsWebVirtualDir
配置数据库管理对象上设置三个属性 -在配置数据库中,您会看到类似以下内容
:会认为这就像检查这三个属性是否存在一样简单,特别是
AppIsolated
属性,因为该属性用于指示应用程序隔离类型(进程内 [0]、进程外 [1] 或池化 [2]) - 每个应用程序都需要此属性。 顺便说一句,在运行 IIS6 的服务器上,如果 IIS 在 IIS5 兼容模式下运行,您只会看到AppIsolated=0|1
。 当您创建自己的应用程序时,应始终设置AppIsolated=2
,这意味着站点或应用程序将在您的应用程序池之一 (w3wp.exe) 中运行。无论如何...由于配置数据库属性继承,检查上面列出的三个属性中的任何一个都不能保证您正在检查的对象实际上是一个应用程序 - 无论是使用 ADSI、WMI 还是 DirectoryServices代码> API。 即使您正在检查的对象只是一个虚拟目录(而不是应用程序),您仍然会得到返回的值,因为它们将从父应用程序继承。
例如,如果
/MyVdir
是位于默认网站中的虚拟目录(不是应用程序),您仍然会看到AppIsolated
的值,这是因为它继承自IIS://Localhost/w3svc/1/root
)。 这同样适用于AppFriendlyName
和AppRoot
属性。我在这里采用的方法是将
DirectoryEntry.Path
属性与目标管理对象上的AppRoot
属性进行比较。AppRoot
是一个属性,指示特定应用程序的根位置。 如果您正在站点元数据库层次结构深处检查 IIS 管理对象,并且需要知道其应用程序的根目录,这会很方便。因此,假设我有一个应用程序位于:
...并假设我们有一个
DirectoryEntry
实例:de.Path
属性将设置为IIS: //Localhost/w3svc/1/root/MyApp
,AppRoot
管理对象属性de.Properties["AppRoot"].Value
将被设置到/LM/W3SVC/1/Root/MyApp
。 您需要做的就是去掉前导的IIS://Localhost
和/LM
字符串,并进行不区分大小写的字符串比较。 如果存在匹配,则该路径上的对象是应用程序。解析 IIS metabase.xml 文件
我过去在死服务器重建作业中使用过另一种方法,其中我们有元数据库文件、我们知道的 vdir 和应用程序的数据库表我们已经创建了它,但没有其他任何东西 - 服务器在弹出之前有 1200 个网站和大量虚拟目录和应用程序。 基本上,我将整个
metabase.xml
文件加载到XMLDocument
中。 然后,我使用 XPath 查找AppIsolated
属性是否存在,其中Location
属性与我感兴趣的路径相匹配。这是一段代码摘录,应该为您提供这个想法的一般要点:
只要应用程序/虚拟目录的周转率不高,解析原始
metabase.xml
文件就可以正常工作。 这是因为内存中元数据库更新不会立即刷新到metabase.xml
文件。 我不建议这样做,我只是为了系统恢复的目的才以这种方式解决问题。System.DirectoryServices 和一些 COM 互操作
最后还有第三种方法(可能是最简单的),如果您的开发 PC 没有运行 IIS6/Windows 2003(我不知道),您可能无法正确测试该方法。没有可用的 XP 计算机来验证这是否适用于 IIS 5.1)。 您要做的就是添加对名为“Active DS IIS Extension Dll”的 COM 库的引用 (
%systemroot%\system32\inetsrv\iisext.dll
),它列在 Visual Studio 的“添加”中的 COM 选项卡上参考对话。 添加此引用时,Visual Studio 还将自动解析并引用依赖项“Active DS 类型库”(%systemroot%\system32\activeds.tlb
)。 在您的解决方案引用文件夹中,您将看到它们列为“ActiveDS”和“IISExt”。使用“Active DS IIS Extension”库,我们可以通过执行以下操作来测试特定路径上的 IIS 管理对象是否实际上是 IIS 应用程序:
还有使用 WMI 的第四种方法,但我只是尝试了一下对于一些相当简单的 IIS/应用程序池管理任务。
There are three ways you can approach this problem:
interop
Plain old System.DirectoryServices
Determining whether an
IIsWebDirectory
or anIIsWebVirtualDir
IIS admin object is configured to be an application usingSystem.DirectoryServices
alone can sometimes be a non-obvious business because of metabase property inheritance.For example, when you create an 'application' there are normally three properties set on the
IIsWebDirectory
orIIsWebVirtualDir
metabase admin objects -In the metabase you would see something like:
Now you would think that it would be as simple as checking for the presence of these three properties, and in particular the
AppIsolated
property because that's the property used to indicate the Application Isolation type (in-process [0], out-of-process [1] or pooled [2]) - and every application requires this property. As a sidenote, on a server running IIS6 you would only seeAppIsolated=0|1
if IIS was running in IIS5 compatibility mode. When you create your own applications you should always setAppIsolated=2
which means the site or application will run in one of your application pools (w3wp.exe).Anyway... because of metabase property inheritance, checking for any of the three properties listed above doesn't guarantee the object you're examining is actually an application - whether it be by using the ADSI, WMI or
DirectoryServices
API's. Even if the object you are checking is just a virtual directory (not application) you'll still get values returned because they would be inherited from the parent application.For example, if
/MyVdir
is a virtual directory (not application) located in the Default Website, you would still see a value forAppIsolated
, this is because it is inherited fromIIS://Localhost/w3svc/1/root
). The same applies with theAppFriendlyName
andAppRoot
properties.The approach I took here was to compare the
DirectoryEntry.Path
property with theAppRoot
property on the target admin object.AppRoot
is a property that indicates where a particular application is rooted. This can be handy if you are examining an IIS admin object deep down in the site's metabase hierarchy and you need to know where its application is rooted at.So, say I had an application located at:
...and say we have an instance of
DirectoryEntry
:The
de.Path
property would be set toIIS://Localhost/w3svc/1/root/MyApp
, theAppRoot
admin object property,de.Properties["AppRoot"].Value
, would be set to/LM/W3SVC/1/Root/MyApp
. All you need to do is strip off the leadingIIS://Localhost
and/LM
strings and do a case-insensitive string compare. If there's a match then the object at that path is an application.Parse the IIS metabase.xml file
There is another way that I've used in the past as part of a dead server rebuild job where we had the metabase file, a database table of vdirs and apps we knew we'd created and not much else - the server had 1200 websites and a multitude of virtual directories and applications before it popped. Basically I loaded the whole
metabase.xml
file into anXMLDocument
. I then used XPath to look for the presence of theAppIsolated
attribute where theLocation
attibute matched the path I was interested in.This is a extract of code that should give you the general jist of the idea:
Parsing the raw
metabase.xml
file works ok as long as there isn't a high turn over of applications/virtual directories. This is because in-memory metabase updates are not flushed to themetabase.xml
file immediately. I wouldn't recommend doing this, I only approached the problem this way purely for the purposes of system recovery.System.DirectoryServices and some COM interop
Finally there is a third way (and probably the simplest) which you may not be able to test properly if your development PC is not running IIS6/Windows 2003 (I don't have an XP machine available to verify if this works with IIS 5.1). What you do is add a reference to a COM library called 'Active DS IIS Extension Dll' (
%systemroot%\system32\inetsrv\iisext.dll
), it's listed on the COM tab in Visual Studio's Add Reference dialogue. When you add this reference, Visual Studio will also automatically resolve and reference a dependency, 'Active DS Type Library' (%systemroot%\system32\activeds.tlb
). In your solution references folder you'll see them listed as 'ActiveDS' and 'IISExt'.Using the 'Active DS IIS Extension' library we can test if an IIS admin object at a particular path is in fact an IIS Application by doing the following:
There is a fourth way using WMI but I've only dipped my toes in the water for some fairly simple IIS/App Pool management tasks.