我有一个使用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");
}
}
}
我相信检查此内容的唯一方法是遍历属性
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;
}
}
[有意/故意导致引发异常通常效率不高;但是,它们都不会遍历整个集合以寻找单个属性。
在您的特定情况下,我会将所有属性的名称存储在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() : "";