usingMicrosoft.Web.Administration;
usingNewtonsoft.Json;
usingNewtonsoft.Json.Linq;
usingoneKeyDeployment.Common.config;
usingoneKeyDeployment.Model;
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Configuration;
usingSystem.IO;
usingSystem.Linq;
usingSystem.Security.Cryptography.X509Certificates;
usingSystem.ServiceProcess;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceoneKeyDeployment.Common
{
/// <summary>
/// 網(wǎng)站發(fā)布幫助類
/// </summary>
publicclassPublishWebHelper
{
/// <summary>
/// 執(zhí)行一鍵部署(單個(gè)網(wǎng)站部署)
/// </summary>
/// <returns></returns>
publicstaticvoidexecute()
{
//IIS 配置信息
varconfig = GetIISConfig();
varvDir = config.VDir;
varapp = config.Applications;
//程序池配置信息
varpoolsConfig = config.ApplicationPools;
variismanager = createServerManager(config);
//創(chuàng)建虛擬目錄
if(vDir !=null&& vDir.Count() > 0)
{
foreach(vardirinvDir)
{
createVDir(config.WebName, dir.DirName, dir.PhysicalPath, iismanager);
}
}
//創(chuàng)建子程序虛擬目錄
foreach(variteminapp)
{
foreach(vardirinitem.VDir)
{
createSubitemVDir(config.WebName, item.Path, dir.DirName, dir.PhysicalPath, iismanager);
}
}
Console.WriteLine("---------------- 程序池 Start ----------------");
//創(chuàng)建程序池
foreach(variteminpoolsConfig)
{
createApplicationPool(item, iismanager);
}
Console.WriteLine("---------------- 程序池 End ----------------");
//提交保存
CommitChanges(iismanager);
}
/// <summary>
/// 創(chuàng)建應(yīng)用程序
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
privatestaticServerManager createServerManager(IISConfig config)
{
varApplicationsConfig = config.Applications;
ServiceController service = ServiceController.GetServices("127.0.0.1").FirstOrDefault(x => x.ServiceName =="W3SVC");
if(serviceisnull)
{
Console.WriteLine("服務(wù)器尚未安裝 IIS 服務(wù)模塊!");
returnnull;
}
if(!System.IO.Directory.Exists(config.WebsiteDirectory))
{
Console.WriteLine("指定目錄不存在!");
returnnull;
}
ServerManager iismanager =newServerManager();
//判斷web應(yīng)用程序是否存在
if(iismanager.Sites[config.WebName] !=null)
{
///移除應(yīng)用程序
iismanager.Sites.Remove(iismanager.Sites[config.WebName]);
}
//建立web應(yīng)用程序(第二個(gè)參數(shù)為安裝文件的地址)
varsite = iismanager.Sites.Add(config.WebName, config.WebsiteDirectory, config.Port);
Console.WriteLine("---------------- 主應(yīng)用程序 Start ----------------");
Console.WriteLine($"網(wǎng)站名稱:{config.ServerDomainName}");
Console.WriteLine($"端口:{config.Port}");
Console.WriteLine($"服務(wù)器域名:{config.ServerDomainName}");
Console.WriteLine($"網(wǎng)站目錄:{config.WebsiteDirectory}");
Console.WriteLine($"程序池名稱:{config.ApplicationPoolName}");
Console.WriteLine("---------------- 主應(yīng)用程序 End ----------------");
Console.WriteLine("---------------- 子程序 Start ----------------");
//設(shè)置子程序 - 應(yīng)用程序池
foreach(variteminApplicationsConfig)
{
varapplication = site.Applications.Add("/"+ item.Path, item.PhysicalPath);
application.ApplicationPoolName = item.ApplicationPoolName;
Console.WriteLine("****************************** ↓");
Console.WriteLine($"子程序路徑名稱:/{item.Path}");
Console.WriteLine($"物理路徑:{item.PhysicalPath}");
}
Console.WriteLine("---------------- 子程序 End ----------------");
//設(shè)置web網(wǎng)站的應(yīng)用程序池
varwebsite = iismanager.Sites[config.WebName];
website.Applications["/"].ApplicationPoolName = config.ApplicationPoolName;
if(!string.IsNullOrEmpty(config.ServerDomainName))
{
stringstr = website.Bindings[0].Host.Split(newchar[] {'.'})[0];
stringbindingInformation = $"*:{config.Port}:{str}{config.ServerDomainName}";
website.Bindings.Add(bindingInformation,"http");
}
returniismanager;
}
/// <summary>
/// 提交更改
/// </summary>
/// <param name="iismanager"></param>
privatestaticvoidCommitChanges(ServerManager iismanager)
{
//提交更改
iismanager.CommitChanges();
}
/// <summary>
/// 創(chuàng)建程序池
/// </summary>
/// <param name="pool"></param>
privatestaticvoidcreateApplicationPool(Model.ApplicationPool poolConfig, ServerManager iismanager)
{
//判斷應(yīng)用程序池是否存在
if(iismanager.ApplicationPools[poolConfig.Name] !=null)
{
//移除應(yīng)用程序池
iismanager.ApplicationPools.Remove(iismanager.ApplicationPools[poolConfig.Name]);
}
//cpu
varcpuConfig = poolConfig.Cpu;
//回收
varrecyclingConfig = poolConfig.Recycling;
//定期重啟
varperiodicRestartConfig = poolConfig.Recycling.PeriodicRestart;
//進(jìn)程孤立
varfailureConfig = poolConfig.Failure;
//進(jìn)程模型
varprocessModelConfig = poolConfig.ProcessModel;
Microsoft.Web.Administration.ApplicationPool pool = iismanager.ApplicationPools.Add(poolConfig.Name);
pool.Name = poolConfig.Name;// 程序池名字
pool.StartMode = poolConfig.StartMode;//啟動(dòng)模式
pool.QueueLength = poolConfig.QueueLength;//隊(duì)列長(zhǎng)度
pool.ManagedRuntimeVersion = poolConfig.ManagedRuntimeVersion;
pool.Enable32BitAppOnWin64 = pool.Enable32BitAppOnWin64;
pool.ManagedPipelineMode = ManagedPipelineMode.Integrated;//托管管道模式
pool.Cpu.Limit = cpuConfig.Limit;//限制最大CPU 50%
pool.Cpu.Action = cpuConfig.Action;//競(jìng)爭(zhēng)cpu時(shí)限制使用最大cpu 百分比
pool.Cpu.ResetInterval =newTimeSpan(00, cpuConfig.ResetInterval, 00);//時(shí)隔5分鐘
pool.Cpu.SmpAffinitized = cpuConfig.SmpAffinitized ??false;
//回收
pool.Recycling.DisallowRotationOnConfigChange = recyclingConfig.DisallowRotationOnConfigChange ??true;//發(fā)生配置更改時(shí)禁止回收
pool.Recycling.DisallowOverlappingRotation = recyclingConfig.DisallowOverlappingRotation ??true;//禁用重疊回收
RecyclingLogEventOnRecycle logEventOnRecycle = RecyclingLogEventOnRecycle.None;
foreach(variteminrecyclingConfig.LogEventOnRecycle)
{
logEventOnRecycle = logEventOnRecycle | item;
}
if(recyclingConfig.LogEventOnRecycle !=null&& recyclingConfig.LogEventOnRecycle.Count() > 0)
pool.Recycling.LogEventOnRecycle = logEventOnRecycle;
foreach(variteminperiodicRestartConfig.Schedule)
{
pool.Recycling.PeriodicRestart.Schedule.Add(item);//定時(shí)回收資源
}
pool.Recycling.PeriodicRestart.PrivateMemory = periodicRestartConfig.PrivateMemory;
pool.Recycling.PeriodicRestart.Time =newTimeSpan(00, periodicRestartConfig.Time, 00);
pool.Recycling.PeriodicRestart.Requests = periodicRestartConfig.Requests;
pool.Recycling.PeriodicRestart.Memory = periodicRestartConfig.Memory;
//進(jìn)程孤立
pool.Failure.OrphanActionParams = failureConfig.OrphanActionParams;
pool.Failure.OrphanActionExe = failureConfig.OrphanActionExe;
pool.Failure.OrphanWorkerProcess = failureConfig.OrphanWorkerProcess ??false;
//模型
pool.ProcessModel.PingInterval =newTimeSpan(00, 00, processModelConfig.PingInterval);
pool.ProcessModel.PingResponseTime =newTimeSpan(00, 00, processModelConfig.PingResponseTime);
pool.ProcessModel.IdentityType = processModelConfig.IdentityType;
pool.ProcessModel.UserName = processModelConfig.UserName;
pool.ProcessModel.Password = processModelConfig.Password;
pool.ProcessModel.ShutdownTimeLimit =newTimeSpan(00, 00, processModelConfig.ShutdownTimeLimit);
pool.ProcessModel.LoadUserProfile = processModelConfig.LoadUserProfile ??false;
pool.ProcessModel.IdleTimeoutAction = IdleTimeoutAction.Terminate;
pool.ProcessModel.StartupTimeLimit =newTimeSpan(00, 00, processModelConfig.StartupTimeLimit);
pool.ProcessModel.PingingEnabled = processModelConfig.PingingEnabled ??false;
pool.ProcessModel.LogEventOnProcessModel = processModelConfig.LogEventOnProcessModel;
pool.ProcessModel.IdleTimeout =newTimeSpan(00, processModelConfig.IdleTimeout, 00);
pool.ProcessModel.MaxProcesses = processModelConfig.MaxProcesses;
Console.WriteLine("****************************** ↓");
Console.WriteLine($"程序池名稱:{poolConfig.Name}");
Console.WriteLine($"隊(duì)列長(zhǎng)度:{poolConfig.QueueLength}");
Console.WriteLine($"啟動(dòng)模式:{poolConfig.StartMode}");
Console.WriteLine($"啟用32位應(yīng)用程序:{poolConfig.Enable32BitAppOnWin64}");
Console.WriteLine($"托管管道模式:{poolConfig.ManagedPipelineMode}");
}
/// <summary>
/// 獲取IIS配置
/// </summary>
/// <returns></returns>
privatestaticIISConfig GetIISConfig()
{
varpath = System.Environment.CurrentDirectory + Config._IISConfigPath;
using(System.IO.StreamReader file = System.IO.File.OpenText(path))
{
using(JsonTextReader reader =newJsonTextReader(file))
{
varo = (JObject)JToken.Readfrom(reader);
returno.ToObject<IISConfig>();
}
}
}
/// <summary>
/// 添加虛擬目錄
/// </summary>
/// <param name="siteName">網(wǎng)站名</param>
/// <param name="vDirName">目錄名</param>
/// <param name="physicalPath">對(duì)應(yīng)的文件夾路徑</param>
/// <param name="iismanager"></param>
privatestaticvoidcreateVDir(stringsiteName,stringvDirName,stringphysicalPath, ServerManager iismanager)
{
Site site = iismanager.Sites[siteName];
if(site ==null)
{
return;
}
site.Applications["/"].VirtualDirectories.Add("/"+ vDirName, physicalPath);
}
/// <summary>
/// 添加虛擬目錄
/// </summary>
/// <param name="siteName">網(wǎng)站名</param>
/// <param name="vDirName">目錄名</param>
/// <param name="physicalPath">對(duì)應(yīng)的文件夾路徑</param>
/// <param name="iismanager"></param>
privatestaticvoidcreateSubitemVDir(stringsiteName,stringsubitemSiteName,stringvDirName,stringphysicalPath, ServerManager iismanager)
{
varapp = iismanager.Sites[siteName].Applications["/"+ subitemSiteName];
if(app ==null)
{
return;
}
app.VirtualDirectories.Add("/"+ vDirName, physicalPath);
}
}
}