C# 远程服务器 创建、修改、删除 应用程序池 网站
首先 C# 操作 站点 需要 引用Microsoft.Web.Administration.dll 文件,创建站点我们一般需要 远程服务的IP,网站名称、端口、物理路径;这里默认网站名称和应用程序池名称一致。
应用程序池默认不启动,应为刚创建站点是没有对应真实的物理文件,修改 队列长度、启动模式、回收时间、最大工作进程, 以及日志路径。修改的时候如果修改站点物理路径的话,我们需要把文件 从旧得目录拷贝到新的目录下,删除站点就比较简单了。
但是站点应用程序池的停止 和启动就比较难搞了,不是调用stop后就马上能停止的,我们需要一个检测状态的机制以及重试机制,如果没有停止 就等待一段时间,因为只有应用程序池完全停止后我们在可以拷贝文件到应用程序目录下;启动也是一样的需要一个 等待 和重试的机制。相关code如下:
#region IIS 操作
/// <summary>
/// 创建IIS site
/// </summary>
/// <param name="serverIP">服务器IP</param>
/// <param name="webName">site 名称</param>
/// <param name="port">site端口</param>
/// <param name="path">site地址</param>
void CreateWebSite(string serverIP, string webName, int port, string path)
{
using (ServerManager sm = ServerManager.OpenRemote(serverIP))
{
//创建应用程序池
ApplicationPool appPool = sm.ApplicationPools.FirstOrDefault(x => x.Name == webName);
if (appPool == null)
{
appPool = sm.ApplicationPools.Add(webName);
appPool.AutoStart = false; appPool.QueueLength = ;
appPool.StartMode = StartMode.AlwaysRunning;//启动模式
appPool.Recycling.PeriodicRestart.Time = new TimeSpan();//回收时间间隔
appPool.ProcessModel.IdleTimeout = new TimeSpan();//闲置超时
appPool.ProcessModel.MaxProcesses = ;//最大工作进程数
}
//创建Site
Site site = sm.Sites.FirstOrDefault(x => x.Name == webName);
if (site == null)
{
//检查远程文件夹是否存在 不存在创建
string remotePath = PathUtil.GetRemotePath(serverIP, path);
if (!Directory.Exists(remotePath))
{
Directory.CreateDirectory(remotePath);
} site = sm.Sites.Add(webName, path, port);
site.ServerAutoStart = true; site.Bindings[].EndPoint.Port = port;
Application root = site.Applications["/"];
root.ApplicationPoolName = webName;
root.VirtualDirectories["/"].PhysicalPath = path;
root.SetAttributeValue("preloadEnabled", true); /*预加载*/ #region 修改日志路径
if (!string.IsNullOrEmpty(ConfigUtil.IISLog))
{
string remoteLog = PathUtil.GetRemotePath(serverIP, ConfigUtil.IISLog);
if (!Directory.Exists(remoteLog))
{
Directory.CreateDirectory(remoteLog);
}
site.LogFile.Directory = ConfigUtil.IISLog;
string failedLog = Path.Combine(ConfigUtil.IISLog, "FailedReqLogFiles");
if (!Directory.Exists(failedLog))
{
Directory.CreateDirectory(failedLog);
}
site.TraceFailedRequestsLogging.Directory = failedLog;
}
#endregion
}
sm.CommitChanges();
}
} /// <summary>
/// 修改IIS站点名 端口 和路径
/// </summary>
/// <param name="serverIP">服务器IP</param>
/// <param name="oldWebName">旧的名称</param>
/// <param name="newWebName">新的web名称</param>
/// <param name="newPort">新的端口</param>
/// <param name="newPath">新的路径</param>
void ModifyWebSite(string serverIP, string oldWebName, string newWebName, int newPort, string newPath)
{
using (ServerManager sm = ServerManager.OpenRemote(serverIP))
{
//修改应用程序池
ApplicationPool appPool = sm.ApplicationPools.FirstOrDefault(x => x.Name == oldWebName);
if (appPool != null && oldWebName != newWebName)
{
appPool.Name = newWebName;
}
//修改Site
Site site = sm.Sites.FirstOrDefault(x => x.Name == oldWebName);
if (site != null)
{
Application root = site.Applications["/"];
if (oldWebName != newWebName)
{
site.Name = newWebName;
root.ApplicationPoolName = newWebName;
} int oldPort = site.Bindings[].EndPoint.Port;
if (oldPort != newPort)
{
var binding = site.Bindings[0];
site.Bindings.RemoveAt(0);
site.Bindings.Add($"*:{newPort}:" + binding.Host, binding.Protocol);
}
string oldPath = root.VirtualDirectories["/"].PhysicalPath;
if (oldPath.ToLower() != newPath.ToLower())
{
string remoteOldPath = PathUtil.GetRemotePath(serverIP, oldPath);
string remoteNewPath = PathUtil.GetRemotePath(serverIP, newPath);
if (!Directory.Exists(remoteNewPath))
{
Directory.CreateDirectory(remoteNewPath);
} //拷贝文件
CopyFiles(remoteOldPath, remoteNewPath); if (Directory.Exists(remoteOldPath))
{
Directory.Delete(remoteOldPath, true);
}
root.VirtualDirectories["/"].PhysicalPath = newPath;
}
}
#region 修改日志路径
if (!string.IsNullOrEmpty(ConfigUtil.IISLog))
{
string remoteLog = PathUtil.GetRemotePath(serverIP, ConfigUtil.IISLog);
if (!Directory.Exists(remoteLog))
{
Directory.CreateDirectory(remoteLog);
}
site.LogFile.Directory = ConfigUtil.IISLog;
string failedLog = Path.Combine(ConfigUtil.IISLog, "FailedReqLogFiles");
if (!Directory.Exists(failedLog))
{
Directory.CreateDirectory(failedLog);
}
site.TraceFailedRequestsLogging.Directory = failedLog;
}
#endregion
sm.CommitChanges();
}
} /// <summary>
/// 删除IIS 站点
/// </summary>
/// <param name="serverIP">服务器地址</param>
/// <param name="webName">站点名</param>
void RemoveWebSite(string serverIP, string webName)
{ string path = string.Empty;
using (ServerManager sm = ServerManager.OpenRemote(serverIP))
{
//删除应用程序池
ApplicationPool appPool = sm.ApplicationPools.FirstOrDefault(x => x.Name == webName);
if (appPool != null)
{
//appPool.Stop();
sm.ApplicationPools.Remove(appPool);
}
//删除Site
Site site = sm.Sites.FirstOrDefault(x => x.Name == webName);
if (site != null)
{
path = site.Applications["/"].VirtualDirectories["/"].PhysicalPath;
sm.Sites.Remove(site);
}
sm.CommitChanges();
}
//删除文件
if (!string.IsNullOrEmpty(path))
{
string remotePath = PathUtil.GetRemotePath(serverIP, path);
if (Directory.Exists(remotePath))
{
Directory.Delete(remotePath, true);
}
}
} /// <summary>
/// 在服务器上检查端口是否被其他站点使用
/// </summary>
/// <param name="webIP">服务器地址</param>
/// <param name="port">端口号</param>
/// <param name="webName">站点名</param>
/// <returns></returns>
bool CheckPortIsUsed(string webIP, string webName, int webPort)
{
bool exist = false;
try
{
using (ServerManager sm = ServerManager.OpenRemote(webIP))
{
List<Site> sites = sm.Sites.ToList();
foreach (Site site in sites)
{
foreach (var item in site.Bindings)
{
if (item.EndPoint != null && item.EndPoint.Port == webPort && site.Name != webName)
{
exist = true;
break;
}
}//end for Bindings
}//end for Site
}
}
catch (Exception ex)
{
throw ex;
}
return exist;
} /// <summary>
/// 停止或启动应用程序池
/// </summary>
/// <param name="serverIP">远程服务器IP</param>
/// <param name="poolNames">应用程序池名称集合</param>
/// <param name="stop">true 停止 false 启动</param>
public void StopAndStartAppPool(string serverIP, string poolName, bool stop = true)
{
using (ServerManager sm = ServerManager.OpenRemote(serverIP))
{
ApplicationPool pool = sm.ApplicationPools.FirstOrDefault(x => x.Name == poolName);
if (pool != null)
{
StopAndStartAppPool(pool, stop);
if (stop)
{
WaiteAppPoolState(pool, ObjectState.Stopped);
}
}
}
} /// <summary>
/// 停止或启动应用程序池
/// </summary>
/// <param name="pool">应用程序池对象</param>
/// <param name="stop">是否是停止</param>
void StopAndStartAppPool(ApplicationPool pool, bool stop = true)
{
Action act = () =>
{
ObjectState poolSate = pool.State;
if (stop && (poolSate == ObjectState.Starting || poolSate == ObjectState.Started))
{
//如果当前应用程序池是启动或者正在启动状态,调用停止方法
pool.Stop();
}
if (!stop && (poolSate == ObjectState.Stopped || poolSate == ObjectState.Stopping))
{
pool.Start();
}
};
int retryCount = ;
int maxCount = ;
while (pool != null && retryCount <= maxCount)
{
try
{
act();
break;
}
catch (Exception ex)
{
retryCount++;
if (retryCount == maxCount)
{
throw new Exception($"{(stop ? "停止" : "启动")}启动应用程序池{pool.Name}出错{ex.Message}");
}
Thread.Sleep( * );
}
}//end while
} /// <summary>
/// 检查引用程序池的状态
/// </summary>
/// <param name="pool">程序池</param>
/// <param name="state">状态</param>
void WaiteAppPoolState(ApplicationPool pool, ObjectState state)
{
int times = ;
while (pool.State != state && times < /*5分钟*/)
{
//检查应用程序池是否已经停止
Thread.Sleep( * );
times++;
}
} /// <summary>
/// 获取应用程序池 和站点的状态
/// </summary>
/// <param name="serverIP">服务器IP</param>
/// <param name="webName">站点名称</param>
/// <returns></returns>
string GetWebState(string serverIP, string webName)
{
ObjectState poolState = ObjectState.Unknown;
ObjectState siteState = ObjectState.Unknown;
using (ServerManager sm = ServerManager.OpenRemote(serverIP))
{
//应用程序池
ApplicationPool appPool = sm.ApplicationPools.FirstOrDefault(x => x.Name == webName);
if (appPool != null)
{
poolState = appPool.State;
} //Site
Site site = sm.Sites.FirstOrDefault(x => x.Name == webName);
if (site != null)
{
siteState = site.State;
}
}
return $"{poolState.ToString()} | {siteState.ToString()}";
}
#endregion
public class ConfigUtil
{
static string _dotNetPath = string.Empty;
public static string DotNetPath
{
get
{
if (string.IsNullOrEmpty(_dotNetPath))
{
string sysDisk = Environment.SystemDirectory.Substring(, );
_dotNetPath = sysDisk + @"WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe";//因为当前用的是4.0的环境
}
return _dotNetPath;
}
} static string _iisLog = string.Empty;
public static string IISLog
{
get
{
if (string.IsNullOrEmpty(_iisLog))
{
_iisLog = ConfigurationManager.AppSettings["IISLog"];
}
return _iisLog;
}
}
}
C# 远程服务器 创建、修改、删除 应用程序池 网站的更多相关文章
- MySQL进阶11--DDL数据库定义语言--库创建/修改/删除--表的创建/修改/删除/复制
/*进阶 11 DDL 数据库定义语言 库和表的管理 一:库的管理:创建/修改/删除 二:表的管理:创建/修改/删除 创建: CREATE DATABASE [IF NOT EXISTS] 库名; 修 ...
- Linux创建修改删除用户和组
Linux 创建修改删除用户和组 介绍 在日常的维护过程中创建用户操作用的相对会多一些,但是在这个过程中涉及到的知识点就不单单就是useradd了,接下来就来详细了解账号管理的相关信息. 用户信息 先 ...
- oracle11g创建修改删除表
oracle11g创建修改删除表 我的数据库名字: ORCL 密码:123456 1.模式 2.创建表 3.表约束 4.修改表 5.删除表 1.模式 set oracle_sid=OR ...
- git 远程服务器创建项目自动化部署、克隆推送免密码
1.用git用户 在git目录下 创建裸仓库 git init --bare project_01.git 2.在裸仓库的 hooks目录下创建 post-receive 文件775 3.post-r ...
- Linux基础学习-用户的创建修改删除
用户添加修改删除 1 useradd添加用户 添加一个新用户hehe,指定uid为3000,家目录为/home/haha [root@qdlinux ~]# useradd -u 3000 -d /h ...
- Linux 创建修改删除用户和组
200 ? "200px" : this.width)!important;} --> 介绍 在日常的维护过程中创建用户操作用的相对会多一些,但是在这个过程中涉及到的知识点就 ...
- ElasticSearch.net NEST批量创建修改删除索引完整示例
本示例采用Elasticsearch+Nest 网上查了很多资料,发现用C#调用Elasticsearch搜索引擎的功能代码很分散,功能不完整,多半是非常简单的操作,没有成型的应用示例.比如新增或修改 ...
- MySQL入门很简单: 4 创建 修改删除表
1. 创建表的方法 1)创建表的语法形式 首先,选择数据库: USE 数据库名: 创建表: CREATE TABLE 表名 (属性名 数据类型 [完整性约束条件], 属性名 数据类型 [完整性约束条件 ...
- SQL Server 创建 修改 删除数据表
1. 图形界面方式操作数据表 (1)创建和修改数据表 列名中如果有两个以上单词时,最好用下划线连接,否则可能会给将来的查询维护带来不便.我们公司美国佬做的数据库就很烦,所有列名都有空格,一旦忘记用方括 ...
随机推荐
- Oracle 相关概念
注:本文来源于 <腾科OCP培训课堂>.非准许商业活动. 标题:Oracle 相关概念 --->数据库名.实例名.数据库域名.全局数据名.服务名 一:数据库名 1:什么是数据库名 ...
- TOP排行新闻列表。
效果图: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...
- 阿里巴巴 Java 开发手册评述
http://blog.jobbole.com/110427 阿里巴巴Java开发手册(终极版)https://pan.baidu.com/s/1c1UQM7Q 阿里巴巴Java开发规约插件p3cGi ...
- maven创建父子关系的聚合项目
我最近使用eclipse的mavean插件创建父子关系的聚合项目,如果创建子工程直接在父工程我相信大家都会创建,但是子工程在父工程中的其中一个文件夹里面,我们创建子工程是直接存在父工程下面的,当我们想 ...
- 点分治 poj1741
题意: 给出一颗树,询问有多少对点对距离<=k 链接: http://poj.org/problem?id=1741 题解: 点分治的模板题 点分治即采用分治思想分而治之 考虑一颗子树内距离&l ...
- 多线程中使用CheckForIllegalCrossThreadCalls = false访问窗口
在多线程程序中,新创建的线程不能访问UI线程创建的窗口控件,如果需要访问窗口中的控件,可以在窗口构造函数中将CheckForIllegalCrossThreadCalls设置为 false publi ...
- C++雾中风景番外篇:理解C++的复杂声明与声明解析
在学习C系列语言的过程之中,理解C/C++的复杂声明一直是初学者很困扰的问题.笔者初学之时也深受困扰,对很多规则死记硬背.后续在阅读<C专家编程>之后,尝试在编译器的角度来理解C/C++的 ...
- 零拷贝-zero copy
Efficient data transfer through zero copy Zero Copy I: User-Mode Perspective 0. 前言 在阅读RocketMQ的官方文档时 ...
- dom那些事儿
一.dom常识1.style属性style对象的属性值都是字符串,设置时必须包括单位,但是不含规则结尾的分号.比如,elem.style.width不能写为100,而要写为100px. 2.getCo ...
- BZOJ.4767.两双手(组合 容斥 DP)
题目链接 \(Description\) 棋盘上\((0,0)\)处有一个棋子.棋子只有两种走法,分别对应向量\((A_x,A_y),(B_x,B_y)\).同时棋盘上有\(n\)个障碍点\((x_i ...