Перезапуск (переработка) пула приложений
Как перезапустить (перезапустить) пул приложений IIS из C# (.net 2)?
Оцените, если вы разместите образец кода?
11 ответов
Джон,
Если вы на 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 приложение перезапустится.
Приведенный ниже метод проверен на работу как для 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;
Использование Null-условного оператора
new ServerManager().ApplicationPools["Your_App_Pool_Name"]?.Recycle();
ИЛИ ЖЕ
Использование условия if для проверки на ноль
var yourAppPool=new ServerManager().ApplicationPools["Your_App_Pool_Name"];
if(yourAppPool!=null)
yourAppPool.Recycle();
Я пошел немного другим путем с моим кодом, чтобы переработать пул приложений. Обратите внимание на несколько вещей, которые отличаются от того, что предоставили другие:
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. Не проверено в 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();
}
}
Вы также можете изменить "Recycle" на "Start" или "Stop".
Переработайте код, работающий на 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()
Вот простое решение, если вы просто хотите переработать все пулы приложений на текущем компьютере. Мне пришлось «запустить от имени администратора», чтобы это сработало.
using (var serverManager = new ServerManager())
{
foreach (var appPool in serverManager.ApplicationPools)
{
appPool.Recycle();
}
}
Другой вариант:
System.Web.Hosting.HostingEnvironment.InitiateShutdown();
Кажется лучше чем UploadAppDomain
который "завершает" приложение, в то время как первый ожидает, что материал завершит свою работу.