75

How can I restart(recycle) IIS Application Pool from C# (.net 2)?

Appreciate if you post sample code?

dove
  • 20,469
  • 14
  • 82
  • 108

11 Answers11

89

Here we go:

HttpRuntime.UnloadAppDomain();
Nathan Ridley
  • 33,766
  • 35
  • 123
  • 197
  • 13
    That recycles the application, but I'm not sure it recycles the entire app-pool (which can host multiple applications at once). – Marc Gravell Jul 04 '09 at 09:48
  • @Marc - very valid, though sometimes you only care about the current application context. The conditions indicating the need to reload may assert themselves independently in each instance. – Nathan Ridley May 08 '11 at 10:04
  • 1
    Very helpful, I've been needing this! (I only need it for the current context) – ThisGuyKnowsCode Jun 30 '11 at 22:11
  • 1
    +1 Im just curious , why would anyone want to recycle his App ? I mean what are the scenarious ( im an asp.net ) developer. – Royi Namir Oct 20 '14 at 07:56
  • 5
    Very useful if you need to remotely recycle your web app (e.g. long-lived / singleton objects are misbehaving) – Aaron Hudon May 21 '15 at 15:59
  • @RoyiNamir - a bit of a necro-post but, if one wanted to clear all session data (for all users) this appears to be the only way to do that. – Jimbo Jul 31 '19 at 13:03
61

If you're on IIS7 then this will do it if it is stopped. I assume you can adjust for restarting without having to be shown.

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

If you're on IIS6 I'm not so sure, but you could try getting the web.config and editing the modified date or something. Once an edit is made to the web.config then the application will restart.

Dale K
  • 25,246
  • 15
  • 42
  • 71
dove
  • 20,469
  • 14
  • 82
  • 108
  • 4
    Oh, go ahead and show him how to adjust for restarting. Do you know how to do it? – DOK Oct 30 '08 at 12:20
  • +1 you are the man. After no less than 10 solutions (including touching web.config), this was the winnar. – ashes999 Feb 02 '12 at 17:34
  • 4
    Hi, this is a very old post but I am struggling to figure one part out. Where does "ServerManagerDemoGlobals.ApplicationPoolArray" come from? i.e. what should I reference to access it? I have added references to Microsoft.Web.Management.dll and Microsoft.Web.Administration.dll Thanks – Jon May 24 '12 at 21:19
  • @Jon I'm also having that problem. – Holger Jun 14 '12 at 11:14
  • @Jon The code seem to originate from here: http://msdn.microsoft.com/en-us/library/microsoft.web.administration.applicationpool%28v=vs.90%29.aspx – Holger Jun 14 '12 at 11:25
  • I was able to satisfy most references by adding the NuGet package Microsoft.Web.Administration. I still cannot find the PropertyBag class. MSDN says it's in Microsoft.Web.Management.Server but I can't find that dll anywhere. Anybody know where it is? – Brad Irby Sep 09 '14 at 13:12
  • 2
    I added a reference to this and it satisfied the attribute and propertyBag c:\windows\SysWOW64\inetsrv\Microsoft.Web.Management.dll (also found in c:\windows\system32\inetsrv\Microsoft.Web.Management.dll) – Brad Irby Sep 09 '14 at 13:28
  • I'm getting an error at line `ApplicationPoolCollection applicationPoolCollection = serverManager.ApplicationPools;` Filename: redirection.config Error: Cannot read configuration file due to insufficient permissions – Mox Shah Nov 14 '14 at 07:19
  • @Jon Unless you need to use the ArrayList to pass on your app pool object, just delete the code and don't sweat it. It's only needed because of the example it appears in on MSDN. – sirdank Feb 06 '15 at 16:32
  • where the hell is ServerManagerDemoGlobals.ApplicationPoolArray?? – peter Apr 09 '16 at 13:32
  • @DOK - To adjust that code for restarting (recycle) the application pool, change: `applicationPool.Start();` To `applicationPool.Recycle();` and remove the `if (applicationPool.State == ObjectState.Stopped)` condition. – BornToCode Jun 26 '16 at 08:56
11

Below method is tested to be working for both IIS7 and IIS8

Step 1 : Add reference to Microsoft.Web.Administration.dll. The file can be found in the path C:\Windows\System32\inetsrv\, or install it as NuGet Package https://www.nuget.org/packages/Microsoft.Web.Administration/

Step 2 : Add the below code

using Microsoft.Web.Administration;

Using Null-Conditional Operator

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

OR

Using if condition to check for null

var yourAppPool=new ServerManager().ApplicationPools["Your_App_Pool_Name"];
if(yourAppPool!=null)
    yourAppPool.Recycle();
Kaarthikeyan
  • 500
  • 5
  • 12
8

I went a slightly different route with my code to recycle the application pool. A few things to note that are different than what others have provided:

1) I used a using statement to ensure proper disposal of the ServerManager object.

2) I am waiting for the application pool to finish starting before stopping it, so that we don't run into any issues with trying to stop the application. Similarly, I am waiting for the app pool to finish stopping before trying to start it.

3) I am forcing the method to accept an actual server name instead of falling back to the local server, because I figured you should probably know what server you are running this against.

4) I decided to start/stop the application as opposed to recycling it, so that I could make sure that we didn't accidentally start an application pool that was stopped for another reason, and to avoid issues with trying to recycle an already stopped application pool.

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);
        }
    }
}
Spazmoose
  • 305
  • 2
  • 9
  • 1
    works good on my iis8, error free just need to add reference Microsoft.Web.Administration as mentioned. – sairfan May 11 '17 at 18:15
8

The code below works on IIS6. Not tested in 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();
    }
}

You can change "Recycle" for "Start" or "Stop" also.

Ricardo Nolde
  • 33,390
  • 4
  • 36
  • 40
5

Recycle code working on 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);
    }
Wolf5
  • 16,600
  • 12
  • 59
  • 58
3

Sometimes I feel that simple is best. And while I suggest that one adapts the actual path in some clever way to work on a wider way on other enviorments - my solution looks something like:

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

From C#, run a DOS command that does the trick. Many of the solutions above does not work on various settings and/or require features on Windows to be turned on (depending on setting).

Simply G.
  • 235
  • 2
  • 9
3

this code work for me. just call it to reload application.

System.Web.HttpRuntime.UnloadAppDomain()
Fred
  • 3,365
  • 4
  • 36
  • 57
1

Here is a simple solution if you just want to recycle all the app pools on the current machine. I had to "run as administrator" for this to work.

using (var serverManager = new ServerManager())
{
    foreach (var appPool in serverManager.ApplicationPools)
    {
        appPool.Recycle();
    }
}
phillhutt
  • 183
  • 1
  • 5
0

Another option:

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

Seems better than UploadAppDomain which "terminates" the app while the former waits for stuff to finish its work.

Alex from Jitbit
  • 53,710
  • 19
  • 160
  • 149