web-dev-qa-db-fra.com

Redémarrage (recyclage) d'un pool d'applications

Comment puis-je redémarrer (recycler) IIS le pool d'applications à partir de C # (.net 2)?

Appréciez si vous postez un exemple de code?

63
John

John,

Si vous êtes sur IIS7 alors cela le fera s'il est arrêté. Je suppose que vous pouvez ajuster pour redémarrer sans avoir à être montré.

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

Si vous êtes sur IIS6 je n'en suis pas si sûr, mais vous pouvez essayer d'obtenir le fichier web.config et d'éditer la date de modification, ou quelque chose du genre. Une fois qu'une modification est apportée à web.config, l'application redémarre.

52
dove

Et c'est parti:

HttpRuntime.UnloadAppDomain();
79
Nathan Ridley
10
alexandrul

J'ai utilisé un code légèrement différent avec mon code pour recycler le pool d'applications. Quelques points à noter qui sont différents de ce que d’autres ont fourni:

1) J'ai utilisé une instruction using pour garantir une élimination appropriée de l'objet ServerManager.

2) J'attends que le pool d'applications ait fini de démarrer avant de l'arrêter afin que nous n'ayons aucun problème à essayer d'arrêter l'application. De même, j'attends que le pool d'applications ait fini de s'arrêter avant d'essayer de le démarrer.

3) Je force la méthode à accepter un nom de serveur réel au lieu de revenir au serveur local, car j’ai pensé que vous devriez probablement savoir sur quel serveur vous exécutez ceci.

4) J'ai décidé de démarrer/arrêter l'application plutôt que de la recycler, afin de m'assurer que nous n'avons pas démarré accidentellement un pool d'applications qui avait été arrêté pour une autre raison et d'éviter tout problème lié à la tentative de recyclage d'une machine déjà arrêtée pool d'applications.

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

Le code ci-dessous fonctionne sur IIS6. Non testé dans 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();
    }
}

Vous pouvez également changer "Recycler" pour "Démarrer" ou "Arrêter".

7
Ricardo Nolde

Recyclez le code fonctionnant sur 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);
    }
5
Wolf5

Parfois, je pense que le plus simple est le mieux. Et même si je suggère que l’on adapte le chemin réel de façon intelligente pour travailler de manière plus large sur d’autres environnements, ma solution ressemble à quelque chose comme:

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

À partir de C #, exécutez une commande DOS qui fait l'affaire. La plupart des solutions ci-dessus ne fonctionnent pas avec différents paramètres et/ou nécessitent l'activation de fonctionnalités sous Windows (selon les paramètres).

2
Simply G.

ce code fonctionne pour moi. Il suffit d'appeler pour recharger l'application.

System.Web.HttpRuntime.UnloadAppDomain()
2
Fred

La méthode ci-dessous est testée pour fonctionner à la fois pour IIS7 et IIS8

Étape 1: Ajoutez une référence à Microsoft.Web.Administration.dll. Le fichier se trouve dans le chemin C:\Windows\System32\inetsrv\ou installez-le en tant que paquet NuGet https://www.nuget.org/packages/Microsoft.Web.Administration/

Étape 2: Ajoutez le code ci-dessous

using Microsoft.Web.Administration;

Utilisation de l'opérateur null-conditionnel

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

OU

Utilisation de la condition if pour rechercher la valeur null

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

Une autre option:

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

Cela semble mieux que UploadAppDomain qui "termine" l'application pendant que l'ancien attend des choses pour terminer son travail.

0
Alex