如何检查PropertyDataCollection中是否存在值?

时间:2014-08-04 18:33:55

标签: c# .net wmi

我有一个类,它使用WMI从服务器收集信息。问题是某些版本的Windows似乎有不同的可用/缺失属性,在尝试访问它们的值之前,我似乎找不到检查集合以查看值是否存在的方法。

要清楚,我发现可以循环遍历整个集合并使用wmiSingle.Properties.GetEnumerator()检查每个属性名称值 - 但必须有更好的方法。正确?

ManagementScope wmiScope = new ManagementScope("\\\\MyLaptop\\root\\cimv2");
ObjectQuery wmiVolumeQuery = new System.Management.ObjectQuery("SELECT * FROM Win32_Processor");

using (ManagementObjectSearcher wmiObjectSearcher = new ManagementObjectSearcher(wmiScope, wmiVolumeQuery))
{
    using (ManagementObjectCollection wmiMany = wmiObjectSearcher.Get())
    {
        foreach (ManagementObject wmiSingle in wmiMany)
        {
            Console.WriteLine(wmiSingle["Name"]);

            //This line will throw an exception. How do I test to see if
            //  "SomeProperty" exists before attempting to access the value?
            //Console.WriteLine(wmiSingle["SomeProperty"]);
            object somePropertyValue = wmiSingle.GetPropertyValue("SomeProperty");
        }
    }
}

2 个答案:

答案 0 :(得分:4)

我认为检查这个的唯一方法是遍历属性

foreach (var prop in wmiSingle.Properties)
{
    if(prop.Name == "SomeProperty")
    { /* do something */ }        
}

你也可以抓住异常 - 比如这个

public static class Extensions
{
    public static object TryGetProperty(this System.Management.ManagementObject wmiObj, string propertyName)
    {
        object retval;
        try
        {
            retval = wmiObj.GetPropertyValue(propertyName);
        }
        catch (System.Management.ManagementException ex)
        {
            retval = null;
        }
        return retval;
    }
}

故意/故意导致抛出异常通常效率不高;但是,它们都没有迭代整个集合来寻找单个属性。

答案 1 :(得分:1)

在您的特定情况下,我会将所有属性的名称存储在HashSet中,然后进行检查。那是非常快的。 尤其是如果您打算在程序生命周期中进行多次检查。

HashSet<string> KnownProperties = new HashSet<string>() { };

然后一次通过属性填充迭代

foreach (PropertyData prop in mo.Properties)
{
     KnownProperties.Add(prop.Name);
}

现在,您可以非常快地获得该值(我对其进行了测试,并获得60个滴答声,其中包含100次迭代= 60ns!)

string Value = KnownProperties.Contains(PropertyName) ? mo[PropertyName].ToString() : "";