簡體   English   中英

如何確定“IIsWebDirectory”或“IIsWebVirtualDir”是否為ASP.NET應用程序?

[英]How do I determine if an “IIsWebDirectory” or “IIsWebVirtualDir” is an ASP.NET Application?

我目前正在編寫一個C#asp.net應用程序來連接到IIS服務器並查詢虛擬目錄/ web目錄信息。

我能夠確定我應該處理的兩種類型是“IIsWebDirectory”和“IIsWebVirtualDir”。

如何確定它們是否已配置為C#中的“應用程序”?

您還可以在此處此處查看我在C#和IIS中的冒險經歷

UPDATE

@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...
            }
        }
    }
}

有三種方法可以解決這個問題:

  • 普通的舊System.DirectoryServices
  • 解析IIS metabase.xml文件
  • System.DirectoryServices和一些COM互操作

普通的舊System.DirectoryServices

確定IIsWebDirectoryIIsWebVirtualDir IIS管理對象是否配置為僅使用System.DirectoryServices的應用程序有時可能是因為配置數據庫屬性繼承IIsWebDirectory明顯的業務。

例如,當您創建“應用程序”時,通常在IIsWebDirectoryIIsWebVirtualDir數據庫管理對象上設置三個屬性 -

AppFriendlyName
AppIsolated
AppRoot

在元數據庫中,您會看到如下內容:

<!-- This is an application -->
<IIsWebVirtualDir   Location ="/LM/W3SVC/1/ROOT/MyApp"
    AccessFlags="AccessRead | AccessScript"
    AppFriendlyName="MyAppKev"
    AppIsolated="2"
    AppRoot="/LM/W3SVC/1/Root/MyApp"    
    >
</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 )。 AppFriendlyNameAppRoot屬性也是如此。

我在這里采用的方法是將DirectoryEntry.Path屬性與目標管理對象上的AppRoot屬性進行比較。 AppRoot是一個屬性,指示特定應用程序的根目錄。 如果您正在檢查站點的元數據庫層次結構中的IIS管理對象,並且您需要知道其應用程序的根源,這可能很方便。

所以,我說有一個應用程序位於:

IIS://Localhost/w3svc/1/root/MyApp

...並說我們有一個DirectoryEntry實例:

DirectoryEntry de = new DirectoryEntry("IIS://Localhost/w3svc/1/root/MyApp");

de.Path屬性將設置為IIS://Localhost/w3svc/1/root/MyAppAppRoot管理對象屬性, de.Properties["AppRoot"].Value ,將設置為/LM/W3SVC/1/Root/MyApp 您需要做的就是剝離領先的IIS://Localhost/LM字符串,並進行不區分大小寫的字符串比較。 如果匹配則該路徑上的對象是應用程序。

解析IIS metabase.xml文件

還有另一種方法我過去曾用過死服務器重建工作,我們有配置數據庫文件,我們知道我們創建的vdirs和應用程序的數據庫表,而不是其他 - 服務器有1200個網站彈出之前的眾多虛擬目錄和應用程序。 基本上我將整個metabase.xml文件加載到XMLDocument 然后我使用XPath來查找AppIsolated屬性的存在,其中Location AppIsolated匹配我感興趣的路徑。

這是代碼的摘錄,應該為您提供該想法的一般要點:

private XmlNamespaceManager _nsm = 
        new XmlNamespaceManager(new NameTable());
private XmlDocument _doc = new XmlDocument();
_doc.Load(@"c:\windows\system32\inetsrv\metabase.xml");
_nsm.AddNamespace("iis", "urn:microsoft-catalog:XML_Metabase_V64_0");

// lmPath could be build from the DirectoryEntry.Path property
string lmPath = "/lm/w3svc/1/root/myapp";

// Try as an IIsWebDirectory object
string iisWebDirectoryXPath = 
    String.Format(@"//iis:IIsWebDirectory[translate(@Location, 
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
            'abcdefghijklmnopqrstuvwxyz') = '{0}']",
            lmPath);

mbNode = _doc.DocumentElement.SelectSingleNode(iisWebDirectoryXPath, _nsm);

if(mbNode != null)
{
    // We found an IIsWebDirectory - is it an application though?
    if (mbNode.Attributes["AppIsolated"] != null)
    {
        // IIsWebDirectory is an Application
    }
}
else
{
    // Is our object an IIsWebVirtualDir?
    string iisWebVirtualDirectoryXPath = 
        String.Format(@"//iis:IIsWebVirtualDir[translate(@Location, 
                'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
                'abcdefghijklmnopqrstuvwxyz') = '{0}']",
                lmPath);

    mbNode = _doc.DocumentElement
            .SelectSingleNode(iisWebVirtualDirectoryXPath, _nsm);

    if (mbNode != null)
    {
        // Yes it's an IIsWebVirtualDir
        if (mbNode.Attributes["Path"] != null)
        {
            if(mbNode.Attributes["AppIsolated"] != null)
            {
                // And it's an application
            }
        }
    }
}

只要沒有很大的應用程序/虛擬目錄轉換,解析原始的metabase.xml文件就可以正常工作。 這是因為內存中的元數據庫更新不會立即刷新到metabase.xml文件。 我不建議這樣做,我只是出於系統恢復的目的這樣才解決問題。

System.DirectoryServices和一些COM互操作

最后還有第三種方式(可能是最簡單的方法),如果您的開發PC沒有運行IIS6 / Windows 2003,您可能無法正常測試(我沒有可用的XP機器來驗證它是否適用於IIS 5.1 )。 您要做的是添加對名為“Active DS IIS Extension Dll”( %systemroot%\\system32\\inetsrv\\iisext.dll )的COM庫的引用,它在Visual Studio的“添加引用”對話框的COM選項卡上列出。 添加此引用時,Visual Studio還將自動解析並引用依賴項“Active DS Type Library”( %systemroot%\\system32\\activeds.tlb )。 在您的解決方案參考文件夾中,您會看到它們被列為“ActiveDS”和“IISExt”。

使用“Active DS IIS Extension”庫,我們可以通過執行以下操作來測試特定路徑上的IIS管理對象是否實際上是IIS應用程序:

using (DirectoryEntry de = 
        new DirectoryEntry("IIS://Localhost/w3svc/1/root/MyApp"))
{
    // Cast our native underlying object to the correct interface
    IISExt.IISApp2 app = (IISExt.IISApp2)de.NativeObject;
    int status = app.AppGetStatus2();

    switch(status)
    {
        case 0:
            Console.WriteLine("It's an app but it's stopped.");
            break;

        case 1:
            Console.WriteLine("It's an app and it's running.");
            break;

        case 2:
            Console.WriteLine("No application found here.");
            break;
    }

}

使用WMI還有第四種方法,但我只是在水中蘸了一些相當簡單的IIS / App Pool管理任務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM