3

I am developing a windows service which will gets the IIS Application Pool status information in every 5 min and stored in database or text file ... like running or stopped.

Getting below exception message:

An exception of type 'System.UnauthorizedAccessException' occurred in Microsoft.Web.Administration.dll but was not handled in user code Additional information: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

Below is the code I have tried:

 static void Main(string[] args)
    {
        const double interval60Minutes = 5 * 5 * 1000; // milliseconds to one hour
        Timer checkForTime = new Timer(interval60Minutes);
        checkForTime.Elapsed += new ElapsedEventHandler(checkForTime_Elapsed);
        checkForTime.Enabled = true;
        Console.WriteLine("Waiting..");           
        Console.ReadLine();          
    }

    public static void checkForTime_Elapsed(object sender, ElapsedEventArgs e)
    {            
        GetApplicationPoolNames();
    }       

    public static string GetApplicationPoolNames()
    {
        ServerManager manager = new ServerManager();
        string status;
        //string DefaultSiteName = System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();
        //Site defaultSite = manager.Sites[DefaultSiteName];
        string appVirtaulPath = HttpRuntime.AppDomainAppVirtualPath;
        string mname = System.Environment.MachineName;
        string appPoolName = string.Empty;
        manager = ServerManager.OpenRemote(mname);
        ObjectState result = ObjectState.Unknown;

        ApplicationPoolCollection applicationPoolCollection = manager.ApplicationPools;

        foreach (ApplicationPool applicationPool in applicationPoolCollection)
        {
            //result = manager.ApplicationPools[appPoolName].State;
            result = applicationPool.State;  *// here exception occures*
            Console.WriteLine("State : " + result);
            Console.ReadLine();
        }
   }

What is wrong in the code? If there are any other ways to achieve this please provide as that will also help me to understand the main cause of exception message.

Any help is appreciated.

Thanks.

Rahul Hendawe
  • 902
  • 1
  • 14
  • 39
  • Did you read the exception message? It's a permission error, "Access is denied". Make sure the user account running the application has all the permissions it needs to access whatever it is you are trying to access. – user1666620 Jun 03 '16 at 11:47
  • check this http://stackoverflow.com/a/27555923/5001784 – Pranav Patel Jun 03 '16 at 11:50
  • @PranavPatel: checked and implemented but no luck. Is there any other ways to achieve this? – Rahul Hendawe Jun 03 '16 at 12:23
  • How did you set your ServiceProcessInstaller.Account in your installer.cs file? Is it ServiceAccount.LocalSystem? If not, try changing it and reinstall your Windows service. – Orkun Bekar Jun 03 '16 at 13:20
  • https://blog.lextudio.com/2015/05/whats-microsoft-web-administration-and-the-horrible-facts-you-should-know/ You can find a few facts from this post. If your case, the service account must be set to Local System I think. – Lex Li Jun 03 '16 at 14:17

1 Answers1

8

The asked question was too old but thought to share the solution which might help someone to resolve this kind of error/exception occurs when trying to get/read the IIS App Pool info of the server.

To resolve the Unauthorized Access Exception while trying to access the IIS info, First provide server credentials using DirectoryEntry Class like below -

DirectoryEntries appPools = new DirectoryEntry("IIS://" + ServerName + "/W3SVC/AppPools", UName, Pwd).Children;

This will give the access of IIS of the respective server.

So, The complete GetApplicationPoolNames() method after modification is -

public static string GetApplicationPoolNames()
{
    // Get Server Credentials and Server Name from config file
    string UName = ConfigurationManager.AppSettings["User"];
    string Pwd = ConfigurationManager.AppSettings["Pass"];
    string ServerName = DT.Rows[i]["ServerName"].ToString().Trim(); //Server Names from db
    DirectoryEntries appPools = null;
    try
    {
        appPools = new DirectoryEntry("IIS://" + ServerName + "/W3SVC/AppPools", UName, Pwd).Children;
    }
    catch(Exception ex)
    {
        log.ErrorFormat("serviceLogic -> InsertStatus() -> IIS Pool App Region -> DirectoryEntries -> Error: ", ex.Message.ToString());
    }

    log.Info("IIS App Pool Section Started for " + System.Environment.MachineName.ToString());

    try
    {
        foreach (DirectoryEntry appPool in appPools)
        {
            log.Info("App Pool : " + appPool.Name.ToString());
            int intStatus = 0;
            string status = "";
            try
            {
                if (appPool.Name.ToString().ToLower().Trim() == DT.Rows[i]["AppPoolSrvName"].ToString().ToLower().Trim())
                {
                    log.Info("Process Started for App Pool : " + appPool.Name.ToString());

                    intStatus = (int)appPool.InvokeGet("AppPoolState");
                    switch (intStatus)
                    {
                        case 2:
                            status = "Running";
                            break;
                        case 4:
                            status = "Stopped";
                            break;
                        default:
                            status = "Unknown";
                            break;
                    }

                    //Store status info to db or file Logic goes here..

                    //Start App pool, If any application pool status is not Running.
                    if (status != "Running")
                        appPool.Invoke("Start", null);

                    log.Info("Process Completed for App Pool : " + appPool.Name.ToString());
                }
            }
            catch (Exception ex)
            {
                log.ErrorFormat("serviceLogic -> InsertStatus() -> IIS Pool App Region -> Error: ", ex.Message);
            }
        }
    }
    catch (Exception ex)
    {
        log.ErrorFormat("serviceLogic -> InsertStatus() -> IIS Pool App Region -> DirectoryEntries -> Error: ", ex.Message);
    }
}
Rahul Hendawe
  • 902
  • 1
  • 14
  • 39