Programmatically get site status from IIS, gets ba

2019-03-30 04:47发布

问题:

I am trying to programmatically get my site status from IIS to see if it's stopped, but I kept getting the following error,

The object identifier does not represent a valid object. (Exception from HRESULT: 0x800710D8)

The application is using ServerManager Site class to access the site status. Here is the code,

//This is fine, gets back the site 
var serverManager = new Microsoft.Web.Administration.ServerManager(ConfigPath);
var site = serverManager.Sites.FirstOrDefault(x => x.Id == 5);
if (site == null) return;
var appPoolName = site.Applications["/"].ApplicationPoolName;
//error!
var state = site.State;

I've test with static site to isolate the issue, making sure that the site is up and running, all configuration are valid, point to the valid application pool...etc.

Let me know if you need more details. Is it the COM thing?

回答1:

I figured out where the problem is. Basically, there are two parts to the Server manager, the first part of the server manager allows you to read site details from configuration file, which is what I've been doing above. The problem with that is you will only able get the information that's in file and site state is not part of it.

The second part of the Server Manager allows you to connect to the IIS directly and it does this by interacting with the COM element. So what I should be doing is this:

ServerManager manager= ServerManager.OpenRemote("testserver");
var site = manager.Sites.First();
var status = site.State.ToString() ;


回答2:

I had a similar problem but mine was caused by the delay needed to activate the changes from the call to CommitChanges on the ServerManager object. I found the answer I needed here:

ServerManager CommitChanges makes changes with a slight delay

It seems like polling is required to get consistent results. Something similar to this solved my problem (I got the exception when accessing a newly added application pool):

        ...
        create new application pool
        ...
        sman.CommitChanges();
        int i = 0;
        const int max = 10;
        do
        {
            i++;
            try
            {
                if (ObjectState.Stopped == pool.State)
                {
                    write_log("Pool was stopped, starting: " + pool.Name);
                    pool.Start();
                }
                sman.CommitChanges();
                break;
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                if (i < max)
                {
                    write_log("Waiting for IIS to activate new config...");
                    Thread.Sleep(1000);
                }
                else
                {
                    throw new Exception(
                        "CommitChanges timed out efter " + max + " attempts.",
                        e);
                }
            }
        } while (true);
        ...