如何从C#(.net 2)重新启动(回收)IIS应用程序池?
感谢您发布示例代码吗?
Answers:
如果您使用的是IIS7,则在停止时将执行此操作。我认为您可以调整以重新启动而无需显示。
// Gets the application pool collection from the server.
[ModuleServiceMethod(PassThrough = true)]
public ArrayList GetApplicationPoolCollection()
{
// Use an ArrayList to transfer objects to the client.
ArrayList arrayOfApplicationBags = new ArrayList();
ServerManager serverManager = new ServerManager();
ApplicationPoolCollection applicationPoolCollection = serverManager.ApplicationPools;
foreach (ApplicationPool applicationPool in applicationPoolCollection)
{
PropertyBag applicationPoolBag = new PropertyBag();
applicationPoolBag[ServerManagerDemoGlobals.ApplicationPoolArray] = applicationPool;
arrayOfApplicationBags.Add(applicationPoolBag);
// If the applicationPool is stopped, restart it.
if (applicationPool.State == ObjectState.Stopped)
{
applicationPool.Start();
}
}
// CommitChanges to persist the changes to the ApplicationHost.config.
serverManager.CommitChanges();
return arrayOfApplicationBags;
}
如果您使用的是IIS6,我不确定,但是您可以尝试获取web.config并编辑修改后的日期或其他内容。对web.config进行编辑后,应用程序将重新启动。
开始了:
HttpRuntime.UnloadAppDomain();
下面的代码在IIS6上有效。未在IIS7中测试。
using System.DirectoryServices;
...
void Recycle(string appPool)
{
string appPoolPath = "IIS://localhost/W3SVC/AppPools/" + appPool;
using (DirectoryEntry appPoolEntry = new DirectoryEntry(appPoolPath))
{
appPoolEntry.Invoke("Recycle", null);
appPoolEntry.Close();
}
}
您也可以将“回收”更改为“开始”或“停止”。
我的代码使用了稍微不同的途径来回收应用程序池。需要注意的几件事与其他提供的不同:
1)我使用了using语句来确保正确处理ServerManager对象。
2)我正在等待应用程序池完成启动,然后再停止它,以便我们在尝试停止应用程序时不会遇到任何问题。同样,我正在等待应用程序池停止运行,然后再尝试启动它。
3)我强迫该方法接受实际的服务器名称,而不是回退到本地服务器,因为我认为您可能应该知道针对该服务器运行的服务器。
4)我决定启动/停止应用程序而不是对其进行回收,以便确保我们不会意外启动由于其他原因而停止的应用程序池,并避免尝试回收已经停止的应用程序的问题应用程序池。
public static void RecycleApplicationPool(string serverName, string appPoolName)
{
if (!string.IsNullOrEmpty(serverName) && !string.IsNullOrEmpty(appPoolName))
{
try
{
using (ServerManager manager = ServerManager.OpenRemote(serverName))
{
ApplicationPool appPool = manager.ApplicationPools.FirstOrDefault(ap => ap.Name == appPoolName);
//Don't bother trying to recycle if we don't have an app pool
if (appPool != null)
{
//Get the current state of the app pool
bool appPoolRunning = appPool.State == ObjectState.Started || appPool.State == ObjectState.Starting;
bool appPoolStopped = appPool.State == ObjectState.Stopped || appPool.State == ObjectState.Stopping;
//The app pool is running, so stop it first.
if (appPoolRunning)
{
//Wait for the app to finish before trying to stop
while (appPool.State == ObjectState.Starting) { System.Threading.Thread.Sleep(1000); }
//Stop the app if it isn't already stopped
if (appPool.State != ObjectState.Stopped)
{
appPool.Stop();
}
appPoolStopped = true;
}
//Only try restart the app pool if it was running in the first place, because there may be a reason it was not started.
if (appPoolStopped && appPoolRunning)
{
//Wait for the app to finish before trying to start
while (appPool.State == ObjectState.Stopping) { System.Threading.Thread.Sleep(1000); }
//Start the app
appPool.Start();
}
}
else
{
throw new Exception(string.Format("An Application Pool does not exist with the name {0}.{1}", serverName, appPoolName));
}
}
}
catch (Exception ex)
{
throw new Exception(string.Format("Unable to restart the application pools for {0}.{1}", serverName, appPoolName), ex.InnerException);
}
}
}
回收在IIS6上工作的代码:
/// <summary>
/// Get a list of available Application Pools
/// </summary>
/// <returns></returns>
public static List<string> HentAppPools() {
List<string> list = new List<string>();
DirectoryEntry W3SVC = new DirectoryEntry("IIS://LocalHost/w3svc", "", "");
foreach (DirectoryEntry Site in W3SVC.Children) {
if (Site.Name == "AppPools") {
foreach (DirectoryEntry child in Site.Children) {
list.Add(child.Name);
}
}
}
return list;
}
/// <summary>
/// Recycle an application pool
/// </summary>
/// <param name="IIsApplicationPool"></param>
public static void RecycleAppPool(string IIsApplicationPool) {
ManagementScope scope = new ManagementScope(@"\\localhost\root\MicrosoftIISv2");
scope.Connect();
ManagementObject appPool = new ManagementObject(scope, new ManagementPath("IIsApplicationPool.Name='W3SVC/AppPools/" + IIsApplicationPool + "'"), null);
appPool.InvokeMethod("Recycle", null, null);
}
经过测试,下面的方法适用于IIS7和IIS8
步骤1:添加对Microsoft.Web.Administration.dll的引用。可以在路径C:\ Windows \ System32 \ inetsrv \中找到该文件,或将其安装为NuGet包https://www.nuget.org/packages/Microsoft.Web.Administration/
步骤2:添加以下代码
using Microsoft.Web.Administration;
使用空条件运算符
new ServerManager().ApplicationPools["Your_App_Pool_Name"]?.Recycle();
要么
使用if条件检查是否为空
var yourAppPool=new ServerManager().ApplicationPools["Your_App_Pool_Name"];
if(yourAppPool!=null)
yourAppPool.Recycle();
有时候我觉得简单是最好的。虽然我建议人们以某种巧妙的方式调整实际路径,以在其他环境中以更广泛的方式工作,但我的解决方案看起来像这样:
ExecuteDosCommand(@"c:\Windows\System32\inetsrv\appcmd recycle apppool " + appPool);
从C#,运行可完成此操作的DOS命令。上面的许多解决方案无法在各种设置上运行和/或需要打开Windows上的功能(取决于设置)。