如何从 C# (.net 2) 重新启动(回收)IIS 应用程序池?
感谢您发布示例代码吗?
开始了:
HttpRuntime.UnloadAppDomain();
如果您在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。未在 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);
}
}
}
以下方法经过测试可用于 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 条件检查 null
var yourAppPool=new ServerManager().ApplicationPools["Your_App_Pool_Name"];
if(yourAppPool!=null)
yourAppPool.Recycle();
回收在 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);
}
有时我觉得简单就是最好的。虽然我建议人们以某种巧妙的方式调整实际路径,以便在其他环境中以更广泛的方式工作 - 我的解决方案看起来像:
ExecuteDosCommand(@"c:\Windows\System32\inetsrv\appcmd recycle apppool " + appPool);
在 C# 中,运行一个 DOS 命令就可以了。上述许多解决方案不适用于各种设置和/或需要打开 Windows 上的功能(取决于设置)。
这段代码对我有用。只需调用它来重新加载应用程序。
System.Web.HttpRuntime.UnloadAppDomain()
另外一个选项:
System.Web.Hosting.HostingEnvironment.InitiateShutdown();
似乎比UploadAppDomain
哪个“终止”应用程序更好,而前者等待工作完成。