tags:

views:

92

answers:

2

Hi ...

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(DeviceID)+'}} 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 ...

A: 

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
François
A: 

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 its 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 ...

Mahmood_N