Problem in getting Result of " Associators of " Statement in WMI Query ( Invalid Variant Operation ! )
I want to Convert this example to Delphi Code , My Problem is in getting result of " Associators of " statement query :
procedure TUSB.GetInfo;
var
WMIService : OLEVariant;
DItems, PItems, LItems, VItems: OLEVariant;
Drive, Partition, Logical, Volume : OLEVariant;
Drives, Partitions, Logicals, Volumes : IEnumVARIANT;
IValue : LongWord;
begin
WMIService := GetWMIObject('winmgmts:\\localhost\root\cimv2');
DItems := WMIService.ExecQuery('select DeviceID, Model from Win32_DiskDrive where InterfaceType='+QuotedStr('USB'));
Drives := IUnKnown(DItems._NewEnum) as IEnumVARIANT;
Drives.Next(1, Drive, IValue);
DeviceID := Drive.Properties_.Item('DeviceID', 0);
PItems := WMIService.ExecQuery('associators of {{Win32_DiskDrive.DeviceID='+QuotedStr(Device开发者_开发技巧ID)+'}} where AssocClass = Win32_DiskDriveToDiskPartition');
Partitions := IUnKnown(PItems._NewEnum) as IEnumVARIANT;
Partitions.Next(1, Partition, IValue);
**PDeviceID := Partition.Properties_.Item('DeviceID', 0);**
...
end;
In the Line marked with 2 star ! I got an Error : " Invalid Variant Operation " while in the above of it in the Same Code , isn`t any error !
what is the Problem ? , in the " Associators of " Statement or ... ?!
thanks a lot ...
Difficult to tell without seeing all the relevant code and declarations.
When you write:
Partitions.Next(1, Partition, IValue);
You should check that you actually get what you want in Partition
.
And more generally, to debug, you should always break your compound statement to test each intermediate step:
Partition.Properties_ // is it correct? how many items?
Partition.Properties_.Item('DeviceID', 0) // if not OK try to iterate through all items
thanks to Francois ...
"Difficult to tell without seeing all the relevant code and declarations."
But there is no more relevant Code ! , I have changed the code following :
procedure TUSBItem.GetInfo;
var
WMIService : OLEVariant;
DItems, PItems, LItems, VItems: OLEVariant;
Drive, Partition, Logical, Volume : OLEVariant;
Drives, Partitions, Logicals, Volumes : IEnumVARIANT;
IValue : LongWord;
begin
WMIService := GetWMIObject('winmgmts:\\localhost\root\cimv2');
DItems := WMIService.ExecQuery('select DeviceID, Model from Win32_DiskDrive where InterfaceType='+QuotedStr('USB'));
Drives := IUnKnown(DItems._NewEnum) as IEnumVARIANT;
while Drives.Next(1, Drive, IValue) = S_OK do
begin
DeviceID := Drive.Properties_.Item('DeviceID', 0);
PItems := WMIService.ExecQuery('associators of {{Win32_DiskDrive.DeviceID='+QuotedStr(DeviceID)+'}} where AssocClass = Win32_DiskDriveToDiskPartition');
Partitions := IUnKnown(PItems._NewEnum) as IEnumVARIANT;
if Partitions.Next(1, Partition, IValue) = S_OK then
begin
if not VarIsNull(Partition) then
PDeviceID := Partition.Properties_.Item('DeviceID', 0);
end;
...
end;
...
end;
In the While loop , for each Drive in Drives Enumerate Variant , I get a "DeviceID" , I Should pass "DeviceID" to " Associators of " statement to get the list of Partition Associated with Drive by "DeviceID" as result of query ...
In the next line , i put the PItems in Partitions as an IEnumVARIANT , next I check if putting first element of Partitions in Partition returned " S_OK " ( Successfully ! ) then i check Partition and if it isnt null then i get one of it
s items named " DeviceID " , but in this line i get an error with this message : " Invalid Variant Operation "
there is Same ways to get DeviceID of Drive and DeviceID of Partition , but when i want to get DeviceID of Partition I got an error , there is an Different between them and its the Query of WMI , I guess the Problem is but i`m not sure !
there is some useful sentences :
" However, you should keep the following in mind when writing your framework provider:
* Make sure you support standard queries in your association class, especially queries where the reference properties are used in a WHERE clause. For more information, see CFrameworkQuery::GetValuesForProp.
* In your association class support, when you check to see if the endpoints exist, ensure you use the CWbemProviderGlue::GetInstanceKeysByPath or CWbemProviderGlue::GetInstancePropertiesByPath methods.
These methods allow the endpoints to skip populating expensive or unneeded properties.
* Make sure any association endpoint classes support per-property Get methods. For more information, see Supporting Partial-Instance Operations. For more information about the query parameter, see CFrameworkQuery. **"**
because of this explains ! , i think that the problem is the Path ! , means i should give my target ( here is Partition ) to the WMIService Object to get the results ! , there is some help of it , but i`m totally confused !!!!
Of course in the Source page that i converting it , isn`t any explain about path ... !
thanks a lot ...
精彩评论