重新启动(回收)应用程序池

如何从 C # (. net 2)重新启动(回收) IIS 应用程序池?

如果您发布样本代码感激吗?

106304 次浏览

如果你在 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 进行了编辑,应用程序将重新启动。

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);
}

下面的代码可以在 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();
}
}

你也可以将“回收”改为“开始”或“停止”。

开始了:

HttpRuntime.UnloadAppDomain();

有时候我觉得简单是最好的。虽然我建议人们以某种聪明的方式调整实际的路径,以便在其他环境中以更广泛的方式工作,但我的解决方案看起来是这样的:

ExecuteDosCommand(@"c:\Windows\System32\inetsrv\appcmd recycle apppool " + appPool);

在 C # 中,运行一个 DOS 命令来完成这个任务。上面的许多解决方案不能在各种设置和/或要求打开 Windows 上的特性(取决于设置)上工作。

我使用了略微不同的代码来回收应用程序池。需要注意的一些事情与其他人提供的不同:

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);
}
}
}

这个代码对我有用。只要调用它重新加载应用程序。

System.Web.HttpRuntime.UnloadAppDomain()

下面的方法被测试为同时适用于 IIS7和 IIS8

步骤1: 添加对 微软。网络。管理。 dll的引用。该文件可以在路径 C: WindowsSystem32inetsrv 中找到,或者将其安装为 NuGetPackagehttps://www.nuget.org/packages/Microsoft.Web.Administration/

步骤2: 添加以下代码

using Microsoft.Web.Administration;

使用空条件运算符

new ServerManager().ApplicationPools["Your_App_Pool_Name"]?.Recycle();

或者

使用 if 条件检查 null

var yourAppPool=new ServerManager().ApplicationPools["Your_App_Pool_Name"];
if(yourAppPool!=null)
yourAppPool.Recycle();

另一个选择:

System.Web.Hosting.HostingEnvironment.InitiateShutdown();

似乎比 UploadAppDomain更好,UploadAppDomain“终止”应用程序,而前者等待东西完成它的工作。

如果你只是想回收当前机器上的所有应用程序池,这里有一个简单的解决方案。我必须“以管理员身份运行”才能工作。

using (var serverManager = new ServerManager())
{
foreach (var appPool in serverManager.ApplicationPools)
{
appPool.Recycle();
}
}