透過 `System.DirectoryServices` 呼叫 ADSI (Active Directory Service Interfaces),可在 C# 中完整管理 IIS 6.0/7.x 的網站、虛擬目錄、應用程式池等設定。本文提供一個 `IISManager` 封裝類,支援建立、查詢、更新、刪除、批次操作虛擬目錄,含屬性對應與錯誤處理。
IISManager
├── Connect(server, siteId) // 連接 IIS://server/W3SVC/siteId/ROOT
├── Create(VirtualDirectory) // 建立虛擬目錄 + AppCreate
├── Update(VirtualDirectory) // 更新屬性
├── Delete(name) // 刪除
├── Exists(name) // 存在性檢查
├── GetVirDir(name) // 取得單一設定
├── UpdateBatch() // 批次提交
└── VirtualDirectories (Hashtable) // 快取集合
VirtualDirectory (資料實體)
├── Name, Path, DefaultDoc
├── AccessRead, AccessWrite, AccessExecute, AccessScript, AccessSSL
├── AuthBasic, AuthNTLM, AuthAnonymous
├── EnableDirBrowsing, EnableDefaultDoc, ContentIndexed
├── AnonymousUserName, AnonymousUserPass
└── flag (0=無變更, 1=新增, 2=更新)
private void ConnectToServer()
{
string path = $"IIS://{_server}/W3SVC/{_website}/ROOT";
try
{
_rootFolder = new DirectoryEntry(path);
_virDirs = GetVirDirs(_rootFolder.Children);
}
catch (Exception ex)
{
throw new Exception($"無法連接 IIS [{_server}]", ex);
}
}
public void Create(VirtualDirectory vd)
{
string adsPath = $"IIS://{_server}/W3SVC/{_website}/ROOT/{vd.Name}";
if (!_virDirs.Contains(vd.Name) || _batchFlag)
{
try
{
// 1. 在 ROOT 下建立 IISWebVirtualDir
DirectoryEntry newDir = _rootFolder.Children.Add(vd.Name, "IISWebVirtualDir");
// 2. 設為應用程式根目錄 (關鍵步驟)
newDir.Invoke("AppCreate", true);
newDir.CommitChanges();
// 3. 寫入屬性
UpdateDirInfo(newDir, vd);
_rootFolder.CommitChanges();
}
catch (Exception ex) { throw new Exception("建立失敗", ex); }
}
else throw new Exception("虛擬目錄已存在");
}
private void UpdateDirInfo(DirectoryEntry de, VirtualDirectory vd)
{
de.Properties["AccessRead"][0] = vd.AccessRead;
de.Properties["AccessWrite"][0] = vd.AccessWrite;
de.Properties["AccessExecute"][0] = vd.AccessExecute;
de.Properties["AccessScript"][0] = vd.AccessScript;
de.Properties["AccessSSL"][0] = vd.AccessSSL;
de.Properties["AuthBasic"][0] = vd.AuthBasic;
de.Properties["AuthNTLM"][0] = vd.AuthNTLM;
de.Properties["AnonymousUserName"][0] = vd.AnonymousUserName;
de.Properties["AnonymousUserPass"][0] = vd.AnonymousUserPass;
de.Properties["ContentIndexed"][0] = vd.ContentIndexed;
de.Properties["EnableDefaultDoc"][0] = vd.EnableDefaultDoc;
de.Properties["EnableDirBrowsing"][0] = vd.EnableDirBrowsing;
de.Properties["DefaultDoc"][0] = vd.DefaultDoc;
de.Properties["Path"][0] = vd.Path;
de.CommitChanges();
}
public void Delete(string name)
{
if (_virDirs.Contains(name))
{
object[] args = { "IISWebVirtualDir", name };
_rootFolder.Invoke("Delete", args);
_rootFolder.CommitChanges();
}
else throw new Exception("虛擬目錄不存在");
}
private VirtualDirectories GetVirDirs(DirectoryEntries entries)
{
var dict = new VirtualDirectories();
foreach (DirectoryEntry de in entries)
{
if (de.SchemaClassName == "IISWebVirtualDir")
{
var vd = new VirtualDirectory
{
Name = de.Name,
Path = (string)de.Properties["Path"][0],
AccessRead = (bool)de.Properties["AccessRead"][0],
// ... 其他屬性同理
Flag = 0
};
dict.Add(vd.Name, vd);
}
}
return dict;
}
var iis = new IISManager("localhost", "1"); // 預設網站 ID=1
iis.Connect();
var vd = new VirtualDirectory
{
Name = "MyApp",
Path = @"C:\Inetpub\wwwroot\MyApp",
AccessRead = true,
AccessScript = true, // 執行 ASP.NET
EnableDefaultDoc = true,
DefaultDoc = "default.aspx,index.html",
AuthNTLM = true
};
iis.Create(vd);
Console.WriteLine("建立完成");
// 批次更新多個
iis.UpdateBatch();
| 項目 | IIS 6 (Metabase/ADSI) | IIS 7+ (applicationHost.config) |
|---|---|---|
| 命名空間 | `System.DirectoryServices` | `Microsoft.Web.Administration` (ServerManager) |
| 虛擬目錄 | `IISWebVirtualDir` | `Application` + `VirtualDirectory` 集合 |
| 應用程式池 | `IISApplicationPool` | `ApplicationPool` 集合 |
| 程式碼相容 | 需啟用 IIS 6 管理相容性 | 原生 API,強型別、LINQ 友善 |
using Microsoft.Web.Administration;
using var sm = new ServerManager();
var site = sm.Sites["Default Web Site"];
var app = site.Applications.Add("/MyApp", @"C:\Inetpub\wwwroot\MyApp");
app.ApplicationPoolName = "MyAppPool";
app.VirtualDirectories[0].PhysicalPath = @"C:\Inetpub\wwwroot\MyApp";
// 設定預設文件
app.VirtualDirectories[0].DefaultDocuments.Clear();
app.VirtualDirectories[0].DefaultDocuments.Add("default.aspx");
sm.CommitChanges();
需引用 `C:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll`,NuGet 亦有 `Microsoft.Web.Administration` 套件。
`System.DirectoryServices` 提供了對 IIS 6 Metabase 的完整程式化存取,`IISManager` 封裝展示了建立、屬性管理、批次操作的核心模式。**現代 IIS 7+ 專案請直接使用 `Microsoft.Web.Administration`**,獲得強型別、配置檔語意、交易式提交等優勢。無論哪種 API,核心邏輯皆為:「連接配置存儲 → 定位節點 → 修改屬性 → 提交變更」。