隐藏

C#操作IIS服务

发布:2021/5/7 16:30:04作者:管理员 来源:本站 浏览次数:1201



从事BS开发到程序猿应该都使用过IIS部署web系统,我也部署过很多次,最近写了一个小程序一键部署web系统,下面分享一下我到实现过程。


1.创建对象,其中包含了一般我们站点部署时设置的参数作为它的属性和字段

复制代码


 public class WebSiteInfo

   {

       //站点设置参数

       public string hostIp { get; set; }  //主机ip

       public string porNum { get; set; }  //端口号

       public string hostName { get; set; }//主机名

       public string webName { get; set; } //网站名

       public string appName { get; set; } //应用程序池

       public string webPath { get; set; } //物理路径

       public string visualName { get; set; } //虚拟目录名称

       public string visualPath { get; set; }//虚拟目录

       public Dictionary<string, string> newMimeType { get; set; }//需要新添加mime类型

       public autherRight autherRight { get; set; }//身份验证模式

       public string defoultPage { get; set; }//默认文档

       public ManagedPipelineMode CXCMS { get; set; }//程序池模式(0:集成;1:经典)

       public string CXCBS { get; set; }//程序池标识

       public bool Is32  { get; set; }//是否32位应用程序

       public int SiteType { get; set; }// 站点类型(0:虚拟目录;1:应用程序)

       public string UserName { get; set; }//用户名称

       public string Password { get; set; }//用户密码

   }


复制代码


2.添加引用


using Microsoft.Web.Administration;  // ServerManger类所属命名空间

using NetFwTypeLib; // 添加引用-COM-搜索NetFwTypeLib(当防火墙打开时,添加入站规则)using System.Net;

using System.Net.NetworkInformation;

using System.ServiceProcess; // 设置文件安全权限类所属命名空间


3.应用程序池操作

复制代码


/// <summary>

/// 获取所有IIS站点

/// </summary>

/// <returns></returns>

public SiteCollection GetAllSite()

{

   var manager = new ServerManager();

   SiteCollection sites = manager.Sites;

   return sites;

}


复制代码

复制代码


       /// <summary>

       /// 创建应用程序池

       /// </summary>

       /// <param name="poolName">应用程序池名称</param>

       /// <param name="enable32BitOn64">是否启用32位应用程序</param>

       /// <param name="runtimeVersion">CLR版本</param>

       /// <param name="mode">经典模式或者集成模式</param>

       public bool CreateAppPool(string poolName, bool enable32BitOn64 = true, string runtimeVersion = "v4.0", bool autoStart = true, ManagedPipelineMode mode = ManagedPipelineMode.Integrated)

       {

           try

           {

               using (var serverManager = new ServerManager())

               {

                   if (serverManager.ApplicationPools[poolName] != null)

                   {

                       return false;

                   }

                   ApplicationPool newPool = serverManager.ApplicationPools.Add(poolName);

                   newPool.ManagedRuntimeVersion = runtimeVersion; // .Net运行版本

                   newPool.Enable32BitAppOnWin64 = enable32BitOn64; // 是否32位应用程序

                   newPool.ManagedPipelineMode = mode; // 集成/经典

                   newPool.AutoStart = autoStart; // 自动启动

                   // 修改程序集标识

                   newPool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser;

                   newPool.ProcessModel.UserName = "Administrator";

                   newPool.ProcessModel.Password = "tlh";

                   serverManager.CommitChanges();

                   return true;

               }

           }

           catch (Exception)

           {

               return false;

           }

       }


复制代码

复制代码


       /// <summary>

       /// 删除应用程序池

       /// </summary>

       /// <param name="poolName">应用程序池名字</param>

       /// <returns></returns>

       public bool DeleteAppPool(string poolName)

       {

           using (var serverManager = new ServerManager())

           {

               var poolObj = serverManager.ApplicationPools[poolName];

               if (poolObj != null)

               {

                   serverManager.ApplicationPools.Remove(poolObj);

               }

               serverManager.CommitChanges();

               return true;

           }

       }


复制代码

复制代码


       /// <summary>

       /// 根据应用程序池名称判断应用程序池是否存在

       /// </summary>

       /// <param name="poolName"></param>

       /// <returns></returns>

       public bool IsAppPoolExisted(string poolName)

       {

           using (var serverManager = new ServerManager())

           {

               var poolObj = serverManager.ApplicationPools[poolName];

               if (poolObj == null)

               {

                   return false;

               }

               return true;

           }

       }


复制代码


4.端口操作

复制代码


       /// <summary>

       /// 判断端口是否被占用

       /// </summary>

       /// <param name="port"></param>

       /// <returns></returns>

       public bool IsPortUsing(int port)

       {

           bool inUse = false;


           IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();

           IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();


           foreach (IPEndPoint endPoint in ipEndPoints)

           {

               if (endPoint.Port == port)

               {

                   inUse = true;

                   break;

               }

           }

           return inUse;

       }


复制代码


5.站点操作

复制代码


       /// <summary>

       /// 获取所有的站点

       /// </summary>

       /// <returns></returns>

       public List<string> GetAllSites()

       {

           using (ServerManager serverManager = new ServerManager())

           {

               return serverManager.Sites.Select(it => it.Name).ToList();

           }

       }


复制代码

复制代码


      /// <summary>

       /// 创建站点

       /// </summary>

       /// <param name="siteName">站点名称</param>

       /// <param name="path">站点路径</param>

       /// <param name="port">端口</param>

       /// <param name="host">主机(*)</param>

       /// <param name="requestType">请求类型:http或者https</param>

       public bool CreateSite(WebSiteInfo webSiteInfo, ref int type)

       {

           try

           {

               using (var serverManager = new ServerManager())

               {

                   var sites = serverManager.Sites;

                   if (sites[webSiteInfo.webName] != null)

                   {// 如果站点存在则删除

                       DeleteSite(webSiteInfo.webName);

                   }

                   /*  是否存在指定端口的网站

                    *  如果存在则在指定端口的站点下面创建应用程序

                    *  否则创建站点

                    */

                   bool flag = false;


                   foreach (var site in sites)

                   {

                       // 获取站点端口号

                       string tempPort = site.Bindings[0].BindingInformation.Split(':')[1];

                       if (tempPort == webSiteInfo.porNum)

                       {

                           if (webSiteInfo.SiteType == 1)

                           { // 创建应用程序

                               Application app = site.Applications.Add("/" + webSiteInfo.webName, webSiteInfo.webPath);

                               app.ApplicationPoolName = webSiteInfo.webName;

                               // 创建虚拟目录

                               VirtualDirectory virtualDic = app.VirtualDirectories.Add("/" + webSiteInfo.visualName, webSiteInfo.visualPath);

                               if (!string.IsNullOrEmpty(webSiteInfo.UserName) && !string.IsNullOrEmpty(webSiteInfo.Password))

                               {

                                   virtualDic.UserName = webSiteInfo.UserName;

                                   virtualDic.Password = webSiteInfo.Password;

                               }

                           }

                           else

                           { // 创建虚拟目录

                               Application app = site.Applications.First();

                               VirtualDirectory virtualDic = app.VirtualDirectories.Add("/" + webSiteInfo.webName, webSiteInfo.webPath);

                               app.ApplicationPoolName = webSiteInfo.webName;

                               if (!string.IsNullOrEmpty(webSiteInfo.UserName) && !string.IsNullOrEmpty(webSiteInfo.Password))

                               {

                                   virtualDic.UserName = webSiteInfo.UserName;

                                   virtualDic.Password = webSiteInfo.Password;

                               }

                           }

                           flag = true;

                           type = 0;

                           break;

                       }

                   }

                   if (!flag)

                   {

                       var site = sites.Add(webSiteInfo.webName, webSiteInfo.webPath, int.Parse(webSiteInfo.porNum));

                       //var site = sites.Add(siteName, requestType, host + ":" + port + ":", path);

                       //绑定程序池

                       site.ApplicationDefaults.ApplicationPoolName = webSiteInfo.webName;

                       type = 1;

                   }

                   serverManager.CommitChanges();

               }

               return true;

           }

           catch (Exception ex)

           {

               return false;

           }

       }


复制代码

复制代码


       /// <summary>

       /// 获取站点

       /// </summary>

       /// <param name="serverManager"></param>

       /// <param name="siteName"></param>

       /// <returns></returns>

       private Site GetSite(ServerManager serverManager, string siteName)

       {

           return serverManager.Sites[siteName];

       }


复制代码

复制代码


       /// <summary>

       /// 判断站点是否存在

       /// </summary>

       /// <param name="siteName"></param>

       /// <returns></returns>

       public bool IsSiteExisted(string siteName)

       {

           using (var serverManager = new ServerManager())

           {

               if (serverManager.Sites[siteName] == null)

               {

                   return false;

               }

               return true;

           }

       }


复制代码

复制代码


       /// <summary>

       /// 删除站点

       /// </summary>

       /// <param name="sitename">站点名称</param>

       /// <returns></returns>

       public bool DeleteSite(string sitename)

       {

           using (var serverManager = new ServerManager())

           {

               var siteObj = serverManager.Sites[sitename];

               if (siteObj != null)

               {

                   serverManager.Sites.Remove(siteObj);

               }

               serverManager.CommitChanges();

               return true;

           }

       }


复制代码


6.IIS操作

复制代码


       /// <summary>

       /// 判断IIS服务器是否存在

       /// </summary>

       /// <returns></returns>

       public bool IsIISExist()

       {

           return ExistService("W3SVC");

       }


       /// <summary>

       /// 判断IIS服务器是否存在

       /// </summary>

       /// <returns></returns>

       public bool ExistService(string serviceName)

       {

           var services = ServiceController.GetServices();

           return services.Count(it => it.ServiceName.Equals(serviceName, StringComparison.Ordinal)) > 0;

       }


       /// <summary>

       /// 判断IIS服务器是否在运行

       /// </summary>

       /// <returns></returns>

       public bool IsIISRunning()

       {

           var services = ServiceController.GetServices();

           return services.Count(it => it.ServiceName == "W3SVC" && it.Status == ServiceControllerStatus.Running) > 0;

       }


复制代码


7.入站规则

复制代码


       /// <summary>

       /// 添加防火墙例外端口

       /// </summary>

       /// <param name="name">名称</param>

       /// <param name="port">端口</param>

       /// <param name="protocol">协议(TCP、UDP)</param>

       public bool AddInRules(string name, int port, string protocol)

       {

           //创建防火墙策略类的实例

           INetFwPolicy2 policy2 = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));

           //检查是否有同名规则

           foreach (INetFwRule item in policy2.Rules)

           {

               if (item.Name == name)

               {

                   return false;

               }

           }

           INetFwRule rule = (INetFwRule)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwRule"));

           //为规则添加名称

           rule.Name = name;

           //为规则添加描述

           rule.Description = "禁止程序访问非指定端口";

           //选择入站规则还是出站规则,IN为入站,OUT为出站

           rule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN;

           //为规则添加协议类型

           rule.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP;

           //为规则添加本地端口

           rule.LocalPorts = port.ToString();

           //为规则添加配置文件类型

           rule.Profiles = (int)NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_ALL;


           //设置规则是阻止还是允许(ALLOW=允许,BLOCK=阻止)

           rule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW;

           //分组名

           rule.Grouping = "";

           rule.InterfaceTypes = "All";


           //是否启用规则

           rule.Enabled = true;

           try

           {

               //添加规则到防火墙策略

               policy2.Rules.Add(rule);

           }

           catch (Exception e)

           {

               return false;

           }

           return true;

       }


复制代码

复制代码


       /// <summary>

       /// 删除防火墙例外端口

       /// </summary>

       /// <param name="ports">端口</param>

       /// <param name="protocol">协议(TCP、UDP)</param>

       public bool DeleteInRules(string ports, string protocol)

       {

           //创建防火墙策略类的实例

           INetFwPolicy2 policy2 = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));

           //string ruleName = System.IO.Path.GetFileNameWithoutExtension(appPath);

           try

           {

               //根据规则名称移除规则

               policy2.Rules.Remove(ports);

           }

           catch (Exception e)

           {

               return false;

           }

           return true;


       }


复制代码


8.自动创建站点

复制代码


       /// <summary>

       /// 创建站点

       /// </summary>

       /// <param name="webSiteInfo"></param>

       private void CreateSite(WebSiteInfo webSiteInfo)

       {

           var iisBll = new IISHelper();

           string websiteName = webSiteInfo.webName;

           string websitePath = webSiteInfo.webPath;//生成站点时绑定的文件物理路径

           int portNumber = int.Parse(webSiteInfo.porNum);//端口

           try

           {

               #region 服务器判断

               if (!iisBll.IsIISExist())

               {

                   MessageBox.Show("请检查IIS服务器服务是否存在!");

                   return;

               }

               if (!iisBll.IsIISRunning())

               {

                   MessageBox.Show("请检查IIS服务器服务是否在运行!");

                   return;

               }

               #endregion


               #region 生成站点


               //创建应用程序池

               if (!iisBll.CreateAppPool(websiteName,webSiteInfo.Is32,"v4.0", true, webSiteInfo.CXCMS))

               {


               }

               int type = 0;// 0:应用程序;1:站点

               //创建站点

               if (!iisBll.CreateSite(webSiteInfo, ref type))

               {

                   //删除应用程序池

                   if (iisBll.IsAppPoolExisted(websiteName))

                   {

                       iisBll.DeleteAppPool(websiteName);

                   }

                   MessageBox.Show("创建站点失败!");

                   return;

               }

               #endregion


               //添加入站规则(防火墙打开时要添加)


               iisBll.AddInRules(portNumber.ToString(), portNumber, "TCP");

               msg.Text = "请在浏览器上输入服务器的IP和端口";

               txtSiteInfo.Text = "http://" + webSiteInfo.hostIp + ":" + webSiteInfo.porNum;

               if (type == 0)

               {

                   txtSiteInfo.Text += "/" + webSiteInfo.webName + "";

               }

               MessageBox.Show("创建站点成功!");

           }

           catch (Exception)

           {

               MessageBox.Show("catch报错!");

           }

       }


复制代码


9.因为虚拟目录一般用来上传文件使用,需要比较多的剩余空间,就想着能不能找到本机所有的盘符,将虚拟目录部署到剩余空间最大的盘符里,代码如下:

复制代码


   /// <summary>

   /// 获取本机盘符空间信息

   /// </summary>

   public class HardDiskPartitionHelper

   {

       /// <summary>

       /// 处理Double值,精确到小数点后几位

       /// </summary>

       /// <param name="_value">值</param>

       /// <param name="Length">精确到小数点后几位</param>

       /// <returns>返回值</returns>

       public static double ManagerDoubleValue(double _value, int Length)

       {

           if (Length < 0)

           {

               Length = 0;

           }

           return System.Math.Round(_value, Length);

       }

       /// <summary>

       /// 获取硬盘上所有的盘符空间信息列表

       /// </summary>

       /// <returns></returns>

       public static List<HardDiskPartition> GetDiskListInfo()

       {

           List<HardDiskPartition> list = null;

           //指定分区的容量信息

           try

           {

               SelectQuery selectQuery = new SelectQuery("select * from win32_logicaldisk");


               ManagementObjectSearcher searcher = new ManagementObjectSearcher(selectQuery);


               ManagementObjectCollection diskcollection = searcher.Get();

               if (diskcollection != null && diskcollection.Count > 0)

               {

                   list = new List<HardDiskPartition>();

                   HardDiskPartition harddisk = null;

                   foreach (ManagementObject disk in searcher.Get())

                   {

                       int nType = Convert.ToInt32(disk["DriveType"]);

                       if (nType != Convert.ToInt32(DriveType.Fixed))

                       {

                           continue;

                       }

                       else

                       {

                           harddisk = new HardDiskPartition();

                           harddisk.FreeSpace = Convert.ToDouble(disk["FreeSpace"]) / (1024 * 1024 * 1024);

                           harddisk.SumSpace = Convert.ToDouble(disk["Size"]) / (1024 * 1024 * 1024);

                           harddisk.PartitionName = disk["DeviceID"].ToString();

                           list.Add(harddisk);

                       }

                   }

               }

           }

           catch (Exception)

           {


           }

           return list;

       }

       /// <summary>

       /// 找到剩余空间最大的盘符,在该盘符下创建指定目录

       /// </summary>

       /// <param name="directoryName"></param>

       /// <returns></returns>

       public static string GetDirectory_FreeSpace_Max(string directoryName)

       {

           string path = "C:\\";

           try

           {

               string partitionName_Max = ""; // 找到剩余空间最大的盘符

               double maxFreeSpace = 0; // 剩余空间

               List<HardDiskPartition> listInfo = HardDiskPartitionHelper.GetDiskListInfo();

               if (listInfo != null && listInfo.Count > 0)

               {

                   foreach (HardDiskPartition disk in listInfo)

                   {

                       if (disk.FreeSpace > maxFreeSpace)

                       {

                           maxFreeSpace = disk.FreeSpace;

                           partitionName_Max = disk.PartitionName;

                       }


                   }

               }

               path = partitionName_Max + "\\" + directoryName;

               if (!Directory.Exists(path))

               {

                   Directory.CreateDirectory(path);

               }

           }

           catch (Exception ex)

           {

               throw ex;

           }

           return path;

       }

   }


复制代码