当从WMI类获取属性SerialNumber
的值时,Win32_CDROMDrive
像这样SELECT SerialNumber FROM Win32_CDROMDrive
它通过NullReferenceException
,除非我将查询更改为SELECT * FROM Win32_CDROMDrive
。然后循环遍历所有属性,包括SerialNumber
in-在这种情况下不为 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%'
或者具体到(对CDROMDrive
的SerialNumber
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");