C#操作IIS服务

从事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;
        }
    }

 

posted @ 2020-04-27 15:30  云淡风轻~江哥  阅读(834)  评论(0编辑  收藏  举报