Thursday 26 April 2012

Recycling Application Pool through Code


Today I'm going to show you how we can recycle application pool programmatically.

Scenario: 
I have a Windows Workflow 4.0 re-hosted designer in which user can create different workflow services and host them at IIS. Every time user create and publish the workflow service, they should be available to use in IIS without manually resetting IIS.

Resolution: We will follow three basic solutions to approach the problem. 

First Solution: Use of ServerManager() class
·        Add a reference of Microsoft.Web.Administration.dll from c:\Windows\System32/inetsrv (I am using Windows7. It could be different depending on the OS installed on your machine)
·        Here's the code snippet that does the thing for you...
               
            var server = new ServerManager();
                var site = server.Sites.FirstOrDefault(s => s.Name == "Default Web Site");
                if (site != null)
                {
         site.Stop();
         if (site.State != ObjectState.Stopped)
         {
             throw new InvalidOperationException("Could not stop website!");
          }
          //restart the site...
           site.Start();
                }
                else
                {
                     throw new InvalidOperationException("Could not find website!");
                }


Drawback: This code can work only on IIS7 or higher. So if you want to make backward compatibility then go for next solution


Second Solution: Use ProcessStartInfo() class

·        The following lines of code dose the thing for you

var startInfo = new ProcessStartInfo("iisreset.exe");
Process.Start(startInfo);
var stopInfo = new ProcessStartInfo("iisreset.exe", " /start");
Process.Start(stopInfo);

Drawback: You should have a cmd window running until iis has been reset properly.


Third Solution: Use of DirectoryService()

·        Add a reference of System.DirectoryService in your application
·        Here the code snippet that does the things for you

StopAppPool();
           int status = CheckAppPoolStatus();
           if (status == 4) StartAppPool();
           while (status != 4)    //4 = AppPool has stopped, 2 = AppPool is Running
           {
               status = CheckAppPoolStatus();
               if (status == 4)
               {
                    StartAppPool();
                }
           }

            private void StopAppPool()
            {
                        try
                        {
                                    var w3Svc = new DirectoryEntry(_appPoolPath);
            w3Svc.Invoke("Stop", null);
                        }
                        catch (Exception ex)
                        {
                                    Utility.ShowMessagebox(DakotaPopupType.Error, ex.Message);
                        }
            }

            private void StartAppPool()
            {
                        try
                        {
                                    var w3Svc = new DirectoryEntry(_appPoolPath);
                                    w3Svc.Invoke("Start", null);
                        }
                        catch (Exception ex)
                        {
                                    Utility.ShowMessagebox(DakotaPopupType.Error, ex.Message);
                        }
            }

            private int CheckAppPoolStatus()
            {
                        int intStatus = 0;
                        try
                        {
                                    var w3Svc = new DirectoryEntry(_appPoolPath);
                                    intStatus = (int)w3Svc.InvokeGet("AppPoolState");
                        }
                        catch (Exception ex)
                        {
                                    Utility.ShowMessagebox(DakotaPopupType.Error, ex.Message);
                        }
                        return intStatus;
            }


The third solution can work on IIS6 as well. I didn’t try it on IIS5 but I think it should work