使用 Visual Studio Web 部署項目安裝後,默認在 IIS 「Default Web Site」下創建虛擬目錄/應用程序。需求是:安裝完成後直接作為**獨立網站**運行(擁有獨立域名/端口/應用程序池),而非子應用程序。
利用 Microsoft.Web.Administration 命名空間(Microsoft.Web.Administration.dll 位於 %windir%\system32\inetsrv),在自定義安裝動作中程序化創建網站、綁定、應用程序池。
using Microsoft.Web.Administration;
using System.DirectoryServices;
public class CustomInstaller : System.Configuration.Install.Installer {
public override void Install(System.Collections.IDictionary stateSaver) {
base.Install(stateSaver);
CreateIndependentWebsite();
}
private void CreateIndependentWebsite() {
// 從安裝參數獲取
string siteName = Context.Parameters["SITE_NAME"] ?? "MyWebApp";
string physicalPath = Context.Parameters["TARGETDIR"]; // 安裝目標目錄
string bindingInfo = Context.Parameters["BINDING"] ?? "*:8080:"; // IP:Port:HostHeader
string appPoolName = siteName + "_AppPool";
string dotNetVersion = "v4.0"; // 或 v2.0
using (ServerManager iis = new ServerManager()) {
// 1. 創建/獲取應用程序池
ApplicationPool pool = iis.ApplicationPools[appPoolName];
if (pool == null) {
pool = iis.ApplicationPools.Add(appPoolName);
pool.ManagedRuntimeVersion = dotNetVersion;
pool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
pool.ProcessModel.IdentityType = ProcessModelIdentityType.ApplicationPoolIdentity;
}
// 2. 刪除同名舊站點(冪等)
Site existing = iis.Sites[siteName];
if (existing != null) {
iis.Sites.Remove(existing);
}
// 3. 創建新站點
Site site = iis.Sites.Add(siteName, "http", bindingInfo, physicalPath);
site.ApplicationDefaults.ApplicationPoolName = appPoolName;
// 可選:設置默認文檔
Configuration config = iis.GetApplicationHostConfiguration();
ConfigurationSection defaultDoc = config.GetSection("system.webServer/defaultDocument", siteName);
defaultDoc["enabled"] = true;
ConfigurationElementCollection files = defaultDoc.GetCollection();
ConfigurationElement add = files.CreateElement("add");
add["value"] = "default.aspx";
files.AddAt(0, add);
iis.CommitChanges();
}
}
public override void Uninstall(System.Collections.IDictionary savedState) {
// 協同卸載:刪除站點與應用程序池
string siteName = Context.Parameters["SITE_NAME"] ?? "MyWebApp";
string appPoolName = siteName + "_AppPool";
using (ServerManager iis = new ServerManager()) {
Site site = iis.Sites[siteName];
if (site != null) iis.Sites.Remove(site);
ApplicationPool pool = iis.ApplicationPools[appPoolName];
if (pool != null) iis.ApplicationPools.Remove(pool);
iis.CommitChanges();
}
base.Uninstall(savedState);
}
}
CustomInstaller 到 Install/Uninstall 節點。SITE_NAME、BINDING(如 *:443:app.example.com 支持 HTTPS)。requireAdministrator),否則 IIS 配置寫入失敗。// 添加 HTTPS 綁定(需預先導入憑證到 My 存儲區)
string certHash = "THUMBPRINT_HEX";
Binding httpsBinding = site.Bindings.CreateElement("binding");
httpsBinding["protocol"] = "https";
httpsBinding["bindingInformation"] = "*:443:app.example.com";
httpsBinding["certificateHash"] = certHash;
httpsBinding["certificateStoreName"] = "My";
httpsBinding["sslFlags"] = (int)SslFlags.Sni; // 啟用 SNI
site.Bindings.Add(httpsBinding);
IIS_IUSRS 或應用程序池標識需對目錄有讀/執行權限,安裝代碼中可調用 DirectorySecurity 自動授權。bindingInfo 端口是否被佔用(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners())。x64,確保加載 Microsoft.Web.Administration.dll 正確版本。通過 ServerManager.Sites.Add 程序化創建獨立網站,徹底擺脫虛擬目錄限制,實現獨立應用程序池、綁定、域名、SSL 配置,是企業級 ASP.NET 部署的標準化路徑。