从事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;
}
}
复制代码
Copyright © 广州京杭网络科技有限公司 2005-2024 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有