问题
When acquiring the value of the property SerialNumber
from the WMI class Win32_CDROMDrive
like this SELECT SerialNumber FROM Win32_CDROMDrive
it throughs a NullReferenceException
unless i change the query to SELECT * FROM Win32_CDROMDrive
. Then loop arround all the properties including the SerialNumber
in-which in that case is not null.
And since the first method is faster than the second (not quite sure) I prefer to use it. So what is happening? Am I missing something? Note that it works perfectly fine with other properties and classes!
This is my code
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);
It won't work unless i change to:
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_CDROMDrive");
Update
The first method works with the other properties of the same class and the value can be extracted without an exception. It seems like the problem is with the SerialNumber
property only!
Update 2
It seems like the problem is indeed with just SerialNumber
as looping arround all the non-nulled-values of properties of the Win32_CDROMDrive
will list the SerialNumber
with a real value as the code below explains:
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());
}
}
However, if the query is changed to the specific wanted property method it will give the same error!
Update 3
I managed to get the value of this naughty property without looping arround all the remaining ones via a different class Win32_PhysicalMedia
which contains less properties for all connected drives (HDD, ODD, Floppy, ...) including the SerialNumber
property using this WQL query
SELECT * FROM Win32_PhysicalMedia
Or to be specific (to the CDROMDrive)
SELECT * FROM Win32_PhysicalMedia WHERE Tag Like '%CD%'
Or to be specific (to the SerialNumber
of the CDROMDrive
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();
But i can't consider this to be an answer as my question is why WQL doesn't allow specifing a record inside the SELECT
statement to the (and only the) SerialNumber
property of the CDROMDrive
class?
回答1:
I just tested on my PC and on my case it seems to be because SerialNumber
property is null on the only instance I have. As it seems, WMI is no working properly when looking for a property that is NULL (that is on my case).
Anyway, you can use ORMi to work with WMI and do all the work using Linq.
Example:
WMIHelper helper = new WMIHelper("root\\CimV2");
var data = helper.Query("SELECT * FROM Win32_CDROMDrive").Where(p => p.SerialNum == "yourSerialNum");
来源:https://stackoverflow.com/questions/51189508/how-come-the-serialnumber-property-of-the-win32-cdromdrive-class-returns-nul