首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 操作 IIS 完全指南:基於 ADSI 的網站管理類庫實現

     編輯:關於C語言

前言:管理 IIS 的兩條路徑

管理 IIS 主要有兩種方式:ADSI (Active Directory Service Interfaces) 和 WMI (Windows Management Instrumentation)。受系統限制 (早期 IIS 版本),本文採用 ADSI 實現。注意:ADSI 操作建議在本地或同網段執行,遠程調用佔用較大帶寬。IIS 6+ 推薦使用 WMI (System.Management) 或 Microsoft.Web.Administration (IIS 7+) 獲得更好體驗。

核心類庫設計:IISAdminLib

靜態類封裝 IIS 基礎操作:創建/刪除網站、啟動/停止、綁定檢查、ID 分配。使用 System.DirectoryServices.DirectoryEntry 訪問 IIS 配置庫 (IIS://localhost/w3svc)。

關鍵實現模塊解析

1. 連接配置與 DirectoryEntry 創建

public static string HostName { get; set; } = "localhost";
public static string UserName { get; set; }
public static string PassWord { get; set; }

public static void RemoteConfig(string host, string user, string pwd)
{
    HostName = host; UserName = user; PassWord = pwd;
}

public static DirectoryEntry GetDirectoryEntry(string path)
{
    if (string.IsNullOrEmpty(UserName))
        return new DirectoryEntry(path); // 本地集成認證
    else
        // 遠程認證:用戶名格式建議 "domain\\user" 或 "user@domain"
        return new DirectoryEntry(path, UserName, PassWord, AuthenticationTypes.Secure);
}

2. 創建新網站

public static void CreateNewWebSite(NewWebSiteInfo siteInfo)
{
    // 1. 檢查綁定衝突
    if (!EnsureNewSiteEnavaible(siteInfo.BindString))
        throw new DuplicatedWebSiteException($"綁定衝突: {siteInfo.BindString}");

    // 2. 獲取根節點並分配新站點 ID
    string rootPath = $"IIS://{HostName}/w3svc";
    using (DirectoryEntry root = GetDirectoryEntry(rootPath))
    {
        string newSiteId = GetNewWebSiteID(); // 獲取最小可用正整數 ID
        using (DirectoryEntry site = root.Children.Add(newSiteId, "IISWebServer"))
        {
            site.CommitChanges(); // 必須先提交創建節點
            
            // 3. 設置核心屬性
            site.Properties["ServerBindings"].Value = siteInfo.BindString; // "IP:Port:HostHeader"
            site.Properties["ServerComment"].Value = siteInfo.CommentOfWebSite; // 站點描述
            site.CommitChanges();

            // 4. 創建根虛擬目錄
            using (DirectoryEntry vdir = site.Children.Add("root", "IISWebVirtualDir"))
            {
                vdir.CommitChanges();
                vdir.Properties["Path"].Value = siteInfo.WebPath; // 物理路徑
                vdir.CommitChanges();
            }
        }
    }
}

3. 刪除網站

public static void DeleteWebSiteByName(string siteName)
{
    string siteId = GetWebSiteNum(siteName); // 通過綁定或描述匹配
    string sitePath = $"IIS://{HostName}/w3svc/{siteId}";
    
    using (DirectoryEntry site = GetDirectoryEntry(sitePath))
    using (DirectoryEntry root = GetDirectoryEntry($"IIS://{HostName}/w3svc"))
    {
        root.Children.Remove(site);
        root.CommitChanges();
    }
}

4. 啟動/停止網站

public static void StartWebSite(string siteName)
{
    string siteId = GetWebSiteNum(siteName);
    using (DirectoryEntry site = GetDirectoryEntry($"IIS://{HostName}/w3svc/{siteId}"))
        site.Invoke("Start", null);
}

public static void StopWebSite(string siteName)
{
    string siteId = GetWebSiteNum(siteName);
    using (DirectoryEntry site = GetDirectoryEntry($"IIS://{HostName}/w3svc/{siteId}"))
        site.Invoke("Stop", null);
}

5. 核心輔助方法

檢查綁定唯一性

public static bool EnsureNewSiteEnavaible(string bindStr)
{
    using (DirectoryEntry root = GetDirectoryEntry($"IIS://{HostName}/w3svc"))
    {
        foreach (DirectoryEntry child in root.Children)
        {
            if (child.SchemaClassName == "IISWebServer" 
                && child.Properties["ServerBindings"].Value?.ToString() == bindStr)
                return false;
        }
    }
    return true;
}

獲取站點 ID (按綁定或描述模糊匹配)

public static string GetWebSiteNum(string siteName)
{
    Regex regex = new Regex(siteName); // 支持正則匹配
    using (DirectoryEntry root = GetDirectoryEntry($"IIS://{HostName}/w3svc"))
    {
        foreach (DirectoryEntry child in root.Children)
        {
            if (child.SchemaClassName != "IISWebServer") continue;
            
            string binding = child.Properties["ServerBindings"].Value?.ToString();
            if (!string.IsNullOrEmpty(binding) && regex.IsMatch(binding))
                return child.Name;
                
            string comment = child.Properties["ServerComment"].Value?.ToString();
            if (!string.IsNullOrEmpty(comment) && regex.IsMatch(comment))
                return child.Name;
        }
    }
    throw new NotFoundWebSiteException($"未找到站點: {siteName}");
}

分配最小可用站點 ID

public static string GetNewWebSiteID()
{
    var ids = new List();
    using (DirectoryEntry root = GetDirectoryEntry($"IIS://{HostName}/w3svc"))
    {
        foreach (DirectoryEntry child in root.Children)
        {
            if (child.SchemaClassName == "IISWebServer" 
                && int.TryParse(child.Name, out int id))
                ids.Add(id);
        }
    }
    ids.Sort();
    int nextId = 1;
    foreach (int id in ids)
    {
        if (id == nextId) nextId++;
        else break;
    }
    return nextId.ToString();
}

數據結構:新站點信息

public struct NewWebSiteInfo
{
    public string HostIP;        // 綁定 IP (如 "192.168.1.100" 或 "All Unassigned" 用 "")
    public string PortNum;       // 端口 (通常 "80")
    public string DescOfWebSite; // 主機頭 (如 "www.example.com")
    public string CommentOfWebSite; // 站點描述/名稱
    public string WebPath;       // 物理路徑 (如 "E:\\WebSites\\MySite")

    public NewWebSiteInfo(string ip, string port, string desc, string comment, string path)
    {
        HostIP = ip; PortNum = port; DescOfWebSite = desc;
        CommentOfWebSite = comment; WebPath = path;
    }

    // IIS ServerBindings 格式: "IP:Port:HostHeader"
    public string BindString => $"{HostIP}:{PortNum}:{DescOfWebSite}";
    public string Comment => CommentOfWebSite;
    public string Path => WebPath;
}

使用示例

// 本地管理
IISAdminLib.CreateNewWebSite(new NewWebSiteInfo("", "8080", "test.local", "測試站點", @"E:\Sites\Test"));
IISAdminLib.StartWebSite("測試站點");

// 遠程管理 (需管理員權限)
IISAdminLib.RemoteConfig("192.168.1.50", "admin", "password");
IISAdminLib.StopWebSite("OldSite");

現代替代方案建議

IIS 版本推薦技術命名空間/套件
IIS 6.0 (WS2003)WMI / ADSISystem.Management / System.DirectoryServices
IIS 7.0+ (WS2008+)Microsoft.Web.AdministrationMicrosoft.Web.Administration.dll (GAC/IIS 安裝目錄)
ASP.NET CoreIWebHost / Kestrel / IIS IntegrationMicrosoft.AspNetCore.Hosting

Microsoft.Web.Administration 物件模型更豐富、類型安全、性能更好,是 IIS 7+ 管理的首選。示例:

using Microsoft.Web.Administration;
using (ServerManager sm = new ServerManager())
{
    Site site = sm.Sites.Add("NewSite", "http", "*:8080:", @"E:\Sites\NewSite");
    sm.CommitChanges();
}

總結

本文提供了基於 ADSI 的 IIS 管理完整類庫,覆蓋站點增刪啟停、綁定檢查、ID 分配等核心功能。理解 DirectoryEntry 操作 IIS 配置庫 (Metabase) 的模式,對維護舊系統、自動化部署腳本極有價值。新項目強烈建議遷移至 Microsoft.Web.Administration 或容器化部署模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved