【问题标题】:how to get the application pool name for a specific website IIS6 programmatically? C#如何以编程方式获取特定网站 IIS6 的应用程序池名称? C#
【发布时间】:2010-10-05 09:44:09
【问题描述】:

如何使用 C# 以编程方式获取特定网站 IIS 6 的应用程序池名称

编辑: 我已经使用了 DirectoryServices 命名空间的方法,但是除非使用相同的代码显式设置它,否则无法正确检索应用程序池名称。这意味着如果您使用 iis 管理器手动添加网站并设置应用程序池,那么当我使用 sharepoint 创建应用程序并设置不同的 appPool 时,这些代码将不起作用(它将始终返回 DefaultAppPool),这些方法不起作用。

【问题讨论】:

    标签: c# iis application-pool


    【解决方案1】:

    System.DirectoryServices namespace 中的课程将帮助您获取这些信息。

    查看this article by Rick Strahl 示例:

    /// <summary>
    /// Returns a list of all the Application Pools configured
    /// </summary>
    /// <returns></returns>
    public ApplicationPool[] GetApplicationPools()
    {           
        if (ServerType != WebServerTypes.IIS6 && ServerType != WebServerTypes.IIS7)
            return null;
    
        DirectoryEntry root = this.GetDirectoryEntry("IIS://" + this.DomainName + "/W3SVC/AppPools");
          if (root == null)
                return null;
    
        List<ApplicationPool> Pools = new List<ApplicationPool>();
    
        foreach (DirectoryEntry Entry in root.Children)
        {
            PropertyCollection Properties = Entry.Properties;
    
            ApplicationPool Pool = new ApplicationPool();
            Pool.Name = Entry.Name;
    
            Pools.Add(Pool);
        }
    
        return Pools.ToArray();
    }
    
    /// <summary>
    /// Create a new Application Pool and return an instance of the entry
    /// </summary>
    /// <param name="AppPoolName"></param>
    /// <returns></returns>
    public DirectoryEntry CreateApplicationPool(string AppPoolName)
    {
        if (this.ServerType != WebServerTypes.IIS6 && this.ServerType != WebServerTypes.IIS7)
            return null;
    
        DirectoryEntry root = this.GetDirectoryEntry("IIS://" + this.DomainName + "/W3SVC/AppPools");
        if (root == null)
            return null;
    
        DirectoryEntry AppPool = root.Invoke("Create", "IIsApplicationPool", AppPoolName) as DirectoryEntry;           
        AppPool.CommitChanges();
    
        return AppPool;
    }
    
    /// <summary>
    /// Returns an instance of an Application Pool
    /// </summary>
    /// <param name="AppPoolName"></param>
    /// <returns></returns>
    public DirectoryEntry GetApplicationPool(string AppPoolName)
    {
        DirectoryEntry root = this.GetDirectoryEntry("IIS://" + this.DomainName + "/W3SVC/AppPools/" + AppPoolName);
        return root;
    }
    
    /// <summary>
    /// Retrieves an Adsi Node by its path. Abstracted for error handling
    /// </summary>
    /// <param name="Path">the ADSI path to retrieve: IIS://localhost/w3svc/root</param>
    /// <returns>node or null</returns>
    private DirectoryEntry GetDirectoryEntry(string Path)
    {
    
        DirectoryEntry root = null;
        try
        {
            root = new DirectoryEntry(Path);
        }
        catch
        {
            this.SetError("Couldn't access node");
            return null;
        }
        if (root == null)
        {
            this.SetError("Couldn't access node");
            return null;
        }
        return root;
    }
    

    【讨论】:

    • 我已经使用了这些方法,但是除非使用相同的代码明确设置,否则无法正确检索应用程序池名称。这意味着如果您使用 iis 管理器手动添加网站并设置应用程序池,这些代码将不起作用(它将始终返回 DefaultAppPool)
    • 当我使用 sharepoint 创建应用程序并设置不同的 appPool 时,这些方法不起作用。
    • 谢谢,我不知道。也许您应该将该信息添加到您的问题中?
    【解决方案2】:

    我不同意你的看法。我编写了一个测试应用程序并从中获得了正确的 AppPool 名称,即使我使用 IIS 管理器手动设置了 AppPool。

    为了确保,我已经测试过一次,name 没问题;然后,我弹出 IIS 管理器,更改 AppPool,执行iisreset,然后再次运行测试应用程序 - 我得到的 AppPool 名称再次正确。我不知道你的代码是什么样的,但我的是这样的:

    using System;
    using System.IO;
    using System.DirectoryServices;
    
    class Class
    {
        static void Main(string[] args)
        {
            DirectoryEntry entry = FindVirtualDirectory("<Server>", "Default Web Site", "<WantedVirtualDir>");
            if (entry != null)
            {
                Console.WriteLine(entry.Properties["AppPoolId"].Value);
            }
        }
    
        static DirectoryEntry FindVirtualDirectory(string server, string website, string virtualdir)
        {
            DirectoryEntry siteEntry = null;
            DirectoryEntry rootEntry = null;
            try
            {
                siteEntry = FindWebSite(server, website);
                if (siteEntry == null)
                {
                    return null;
                }
    
                rootEntry = siteEntry.Children.Find("ROOT", "IIsWebVirtualDir");
                if (rootEntry == null)
                {
                    return null;
    
                }
    
                return rootEntry.Children.Find(virtualdir, "IIsWebVirtualDir");
            }
            catch (DirectoryNotFoundException ex)
            {
                return null;
            }
            finally
            {
                if (siteEntry != null) siteEntry.Dispose();
                if (rootEntry != null) rootEntry.Dispose();
            }
        }
    
        static DirectoryEntry FindWebSite(string server, string friendlyName)
        {
            string path = String.Format("IIS://{0}/W3SVC", server);
    
            using (DirectoryEntry w3svc = new DirectoryEntry(path))
            {
                foreach (DirectoryEntry entry in w3svc.Children)
                {
                    if (entry.SchemaClassName == "IIsWebServer" &&
                        entry.Properties["ServerComment"].Value.Equals(friendlyName))
                    {
                        return entry;
                    }
                }
            }
            return null;
        }
    }
    

    对不起我糟糕的英语。
    希望我有所帮助。

    【讨论】:

    • 不错,适用于 IIS7 和 IIS6。请记住,如果您的服务始终以与根级别相同的身份运行,则您不一定需要为虚拟目录识别 AppPool。另外,如果找不到网站,我不确定是否将空值传回:我宁愿让系统抛出。
    • 很高兴知道它也适用于 IIS7!关于“捕获”,我同意 - 你应该做最适合你的事情!
    • 根据stackoverflow.com/q/249927/496357#comment11785064_496357 的评论,您可能需要在 IIS7 上启用“IIS 6 WMI 兼容性”才能使其工作。
    【解决方案3】:

    简而言之,有两种方法可以做到这一点。

    不太复杂的方法是知道,IIS6 的设置存储在 MetaBase 中,它只是一个 Xml 文件:

    C:\WINDOWS\system32\inetsrv\MetaBase.xml
    

    您可以只使用 Linq2Xml 并解析 Xml 以查找站点名称或 Id,AppPoolId 属性包含 AppPool 的名称

    正确的方法是使用 System.DirectoryServices

    【讨论】:

      猜你喜欢
      • 2010-09-19
      • 1970-01-01
      • 1970-01-01
      • 2012-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多