为什么 "Win32_CDROMDrive" 类的 "SerialNumber" 属性在与 WMI 分开请求时返回 null?



当从WMI类获取属性SerialNumber的值时,Win32_CDROMDrive像这样SELECT SerialNumber FROM Win32_CDROMDrive它通过NullReferenceException,除非我将查询更改为SELECT * FROM Win32_CDROMDrive。然后循环遍历所有属性,包括SerialNumberin-在这种情况下不为 null。

而且由于第一种方法比第二种方法更快(不太确定(,我更喜欢使用它。那么这是怎么回事呢?我错过了什么吗? 请注意,它与其他属性和类完美配合!

这是我的代码

string result = "";
var searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_CDROMDrive");
ManagementObjectCollection collec = searcher.Get();
foreach (ManagementObject obj in collec)
{
result = obj["SerialNumber"].ToString();
break;
}
MessageBox.Show(result);

除非我更改为:

var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_CDROMDrive");

更新

第一种方法适用于同一类的其他属性,并且可以毫无例外地提取值。似乎问题只出在SerialNumber属性上!

更新 2

似乎问题确实出在SerialNumber因为循环Win32_CDROMDrive属性的所有非空值将列出具有实际值的SerialNumber,如下面的代码所示:

listView1.Items.Clear();
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_CDROMDrive");
foreach (ManagementObject mo in searcher.Get())
{
foreach (PropertyData pd in mo.Properties)
{
if (pd.Value != null)
listView1.Items.Add(pd.Name).SubItems.Add(pd.Value.ToString());
}
}

但是,如果将查询更改为特定的所需属性方法,它将给出相同的错误!

更新 3

我设法获取了这个顽皮属性的值,而无需通过不同的类Win32_PhysicalMedia循环所有剩余的属性,该类包含所有连接的驱动器(HDD、ODD、Floppy 等(的较少属性,包括使用此 WQL 查询的SerialNumber属性

SELECT * FROM Win32_PhysicalMedia

或者具体到(对CDROMDrive(

SELECT * FROM Win32_PhysicalMedia WHERE Tag Like '%CD%'

或者具体到(对CDROMDriveSerialNumber

SELECT SerialNumber FROM Win32_PhysicalMedia WHERE Tag Like '%CD%'

var searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_PhysicalMedia WHERE TAG LIKE '%CD%'");
ManagementObjectCollection collec = searcher.Get();
foreach (ManagementObject obj in collec)
{
Console.WriteLine(obj["SerialNumber"].ToString());
}
Console.Read();

但我不能认为这是一个答案,因为我的问题是为什么 WQL 不允许在SELECT语句中为CDROMDrive类的SerialNumber属性指定记录?

我刚刚在我的 PC 上进行了测试,就我而言SerialNumber这似乎是因为属性在我拥有的唯一实例上为 null。看起来,在查找 NULL 的属性时,WMI 无法正常工作(在我的情况下(。

无论如何,您可以使用 ORMi 与 WMI 一起工作,并使用 Linq 完成所有工作。

例:

WMIHelper helper = new WMIHelper("root\CimV2");
var data = helper.Query("SELECT * FROM Win32_CDROMDrive").Where(p => p.SerialNum == "yourSerialNum");

最新更新