it-swarm.com.de

Neustarten (Recycling) eines Anwendungspools

Wie kann ich den IIS -Anwendungspool von C # (.net 2) aus neu starten (recyceln)?

Schätzen, wenn Sie Beispielcode posten?

63
John

John,

Wenn Sie sich auf IIS7 befinden, führt dies das Programm aus, wenn es gestoppt wird. Ich gehe davon aus, dass Sie den Neustart anpassen können, ohne angezeigt zu werden.

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

Wenn Sie sich auf IIS6 befinden, bin ich mir nicht so sicher, aber Sie könnten versuchen, die web.config zu erhalten und das geänderte Datum oder etwas zu ändern. Sobald die web.config bearbeitet wurde, wird die Anwendung neu gestartet.

52
dove

Auf geht's:

HttpRuntime.UnloadAppDomain();
79
Nathan Ridley
10
alexandrul

Ich ging mit meinem Code eine etwas andere Route, um den Anwendungspool zu recyceln. Ein paar Dinge zu beachten, die sich von den anderen unterscheiden:

1) Ich habe eine using-Anweisung verwendet, um die ordnungsgemäße Entsorgung des ServerManager-Objekts sicherzustellen.

2) Ich warte auf den Start des Anwendungspools, bevor er beendet wird, damit wir keine Probleme mit dem Versuch haben, die Anwendung zu stoppen. Ebenso warte ich auf den Stopp des App-Pools, bevor ich ihn starten kann.

3) Ich zwinge die Methode, einen tatsächlichen Servernamen zu akzeptieren, anstatt auf den lokalen Server zurückzugreifen, da ich dachte, Sie sollten wahrscheinlich wissen, gegen welchen Server Sie dies ausführen.

4) Ich habe mich entschieden, die Anwendung zu starten oder zu stoppen, anstatt sie zu recyceln, um sicherzustellen, dass wir nicht versehentlich einen Anwendungspool starten, der aus einem anderen Grund gestoppt wurde, und um Probleme mit dem Versuch zu vermeiden, ein bereits gestopptes Programm wiederzuverwenden Anwendungspool.

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

Der folgende Code funktioniert auf IIS6. Nicht in IIS7 getestet.

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

Sie können "Recycling" auch für "Start" oder "Stopp" ändern.

7
Ricardo Nolde

Recyclingcode für 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

Manchmal finde ich, dass es am einfachsten ist. Und obwohl ich vorschlage, dass man den tatsächlichen Pfad auf eine clevere Art und Weise anpasst, um an anderen Umgebungen weiter zu arbeiten, sieht meine Lösung in etwa so aus:

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

Führen Sie in C # einen DOS-Befehl aus, der den Trick ausführt. Viele der oben genannten Lösungen funktionieren bei verschiedenen Einstellungen nicht und/oder erfordern die Aktivierung von Windows-Funktionen (je nach Einstellung).

2
Simply G.

dieser Code funktioniert für mich. Rufen Sie es einfach auf, um die Anwendung neu zu laden.

System.Web.HttpRuntime.UnloadAppDomain()
2
Fred

Die nachstehende Methode wurde getestet, um sowohl für IIS7 als auch für IIS8 zu funktionieren

Schritt 1: Fügen Sie einen Verweis auf Microsoft.Web.Administration.dll hinzu. Die Datei befindet sich im Pfad C:\Windows\System32\inetsrv\oder kann als NuGet Package https://www.nuget.org/packages/Microsoft.Web.Administration/ installiert werden.

Schritt 2: Fügen Sie den folgenden Code hinzu

using Microsoft.Web.Administration;

Verwenden eines nullbedingten Operators

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

ODER

Verwendung der if-Bedingung zur Überprüfung auf null

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

Andere Option:

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

Scheint besser zu sein als UploadAppDomain, wodurch die App "beendet" wird, während die App darauf wartet, dass die Arbeit beendet wird.

0
Alex