检查 IIS 应用程序池的状态

Rah*_*awe 3 c# iis windows-services application-pool

我正在开发一个 Windows 服务,它将每 5 分钟获取一次 IIS 应用程序池状态信息并存储在数据库或文本文件中......比如运行或停止。

获取以下异常消息:

Microsoft.Web.Administration.dll 中出现“System.UnauthorizedAccessException”类型的异常,但未在用户代码中处理附加信息:访问被拒绝。(来自 HRESULT 的异常:0x80070005 (E_ACCESSDENIED))

下面是我试过的代码:

 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();
        }
   }
Run Code Online (Sandbox Code Playgroud)

代码有什么问题?如果有任何其他方法可以实现这一点,请提供,因为这也将帮助我了解异常消息的主要原因。

任何帮助表示赞赏。

谢谢。

Rah*_*awe 6

提出的问题太老了,但想分享可能有助于解决此类错误/异常的解决方案,在尝试获取/读取服务器的 IIS 应用程序池信息时发生。

要在尝试访问 IIS 信息时解决未经授权的访问异常,首先使用DirectoryEntry 类提供服务器凭据,如下所示 -

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

这将提供对相应服务器的 IIS 的访问权限。

所以,GetApplicationPoolNames()修改后的完整方法是——

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);
    }
}
Run Code Online (Sandbox Code Playgroud)