在使用VMWare Vsphere Webservice API进行开发时,其中最常用到的一个方法就是查找对象的属性的功能:_service.RetrieveProperties(); 下面是一段查找物理机相关信息(获取所有物理机的电源及通信状态)的代码:

  protected SelectionSpec[] GetAllPMStatusesSearchPath()
   {
            TraversalSpec crTohs = new TraversalSpec();
            crTohs.name = "crTohs";
            crTohs.type = "ComputeResource";
            crTohs.skip = false;
            crTohs.skipSpecified = true;
            crTohs.path = "host";

            TraversalSpec dcTocr = new TraversalSpec();
            dcTocr.name = "dcTocr";
            dcTocr.type = "Datacenter";
            dcTocr.skip = false;
            dcTocr.skipSpecified = true;
            dcTocr.path = "hostFolder";
            dcTocr.selectSet = new SelectionSpec[] { new SelectionSpec() };
            dcTocr.selectSet[0].name = "folderTochild";

            TraversalSpec folderTochild = new TraversalSpec();
            folderTochild.name = "folderTochild";
            folderTochild.skip = false;
            folderTochild.skipSpecified = true;
            folderTochild.type = "Folder";
            folderTochild.path = "childEntity";
            folderTochild.selectSet = new SelectionSpec[] { new SelectionSpec(), new SelectionSpec(),

                                                                                       new SelectionSpec() };
            folderTochild.selectSet[0].name = "folderTochild";
            folderTochild.selectSet[1].name = "dcTocr";
            folderTochild.selectSet[2].name = "crTohs";

            return new SelectionSpec[] { folderTochild, crTohs, dcTocr };
 }

protected PropertyFilterSpec[] GetAllPMStatusesPropFilter()
 {
            PropertyFilterSpec propFilterSpec = new PropertyFilterSpec();
            propFilterSpec.objectSet = new ObjectSpec[] { new ObjectSpec() };
            propFilterSpec.objectSet[0].obj = _sc.rootFolder;
            propFilterSpec.objectSet[0].skip = false;
            propFilterSpec.objectSet[0].skipSpecified = true;
            propFilterSpec.objectSet[0].selectSet = GetAllPMStatusesSearchPath();
            propFilterSpec.propSet = new PropertySpec[] { new PropertySpec()};
            propFilterSpec.propSet[0].all = false;
            propFilterSpec.propSet[0].allSpecified = true;
            propFilterSpec.propSet[0].type = "HostSystem";
            propFilterSpec.propSet[0].pathSet = new string[] { "name", "runtime.powerState",

                                                                                                       "runtime.connectionState" };          

            return new PropertyFilterSpec[] { propFilterSpec };
    }

 /// <summary>
 /// 获取所有物理机的电源及通信状态
 /// </summary>
 /// <returns></returns>
public PMStatus[] GetAllPMStatus()
{
            ObjectContent[] ocs = null;
            try
            {
               ocs = _service.RetrieveProperties(_sc.propertyCollector, GetAllPMStatusesPropFilter());
            }
            catch (Exception ex)
            {
                throw new Exception("查找所有物理主机的电源状态及通信状态时出错: " + ex.Message);
            }
            ArrayList pmStatuses = new ArrayList();
            foreach (ObjectContent oc in ocs)
            {
                PMStatus status = new PMStatus(); //这是我定义的类型
                status.PMUuid = oc.obj.Value;
                foreach (DynamicProperty dp in oc.propSet)
                {
                    switch (dp.name)
                    {
                        case "name":
                            status.PMName = dp.val as string;
                            break;
                        case "runtime.powerState":
                            HostSystemPowerState powerState = (HostSystemPowerState)dp.val;
                            switch (powerState)
                            {
                                case HostSystemPowerState.poweredOff:
                                    status.powerState = PMPowerState.poweredOff;
                                    break;
                                case HostSystemPowerState.poweredOn:
                                    status.powerState = PMPowerState.poweredOn;
                                    break;
                                case HostSystemPowerState.standBy:
                                    status.powerState = PMPowerState.standBy;
                                    break;
                                case HostSystemPowerState.unknown:
                                    status.powerState = PMPowerState.unknown;
                                    break;
                                default:
                                    break;
                            }
                            break;
                        case "runtime.connectionState":
                            HostSystemConnectionState connState = (HostSystemConnectionState)dp.val;
                            if (connState == HostSystemConnectionState.connected)
                            {
                                status.communiteState = PMCommuniteState.Normal;
                            }
                            else
                            {
                                status.communiteState = PMCommuniteState.Exceptional;
                            }
                            break;
                        default:
                            break;
                    }
                }
                pmStatuses.Add(status);
            }
            return (PMStatus[])pmStatuses.ToArray(typeof(PMStatus));
}       

上面红色标注的语句的执行过程我将在下面以伪代码的形式进行说明

//start:为查找的起始节点;
//skip:true,则表示不在start上进行查找;false:表示要在start进行查找
//paths:是查找时所使用的路径,用于引导查找前进;
//dstType:要查找的类型,比如:如果我们要查找虚拟机,则dstType置为VirtualMachine;
//properties:对应dstType的属性集合,比如:如果dstTye=VirtualMachine,则我们可以查找它的名字,电源状态,是否为模板等属性的值
ObjectContent[] RetrieveProperties(ManagedObjectReference start,bool skip;SelectionSpec[] paths,string dstType,string[] properties)
{
   ArrayList returnValues = new ArrayList(); //用于存放返回值
   ManagedObjectReference  currentNode = start;
   if(currentNode未曾访问过)
   {    
      标记currentNode为已访问;
      if(skip==false && currentNode.type==dstType)
      {
         在currentNode上查找properties中指定的属性并将这些查找结果生成一个对应currentNode的ObjectContent类型的对象oc;
         returnValues.Add(oc);
      }
   }
   else
   {  return null; }  
   foreach(SelectionSpec path in paths)
   {
      if(path.type==currentNode.type)
      {
          foreach(ManagedObjectReference nextStart in [path.path属性中的所有项])
          {
             ObjectContent[] ocs=RetrieveProperties(nextStart,path.skip,dstType,properties); //递归调用
             if(ocs!=null)

             {

                  foreach(ObjectContent oc in ocs)

                  {

                       returnValues.Add(oc);

                  }

              }
          }
      }
   }
   return (ObjectContent[])returnValues.ToArray(typeof(ObjectContent));
}
前面的红色语句:_service.RetrieveProperties(_sc.propertyCollector, GetAllPMStatusesPropFilter()  相当于以下调用:

RetrieveProperties(propFilterSpec.objectSet[0].obj ,propFilterSpec.objectSet[0].skip ,

propFilterSpec.objectSet[0].selectSet ,propFilterSpec.propSet[0].type ,propFilterSpec.propSet[0].pathSet );