在WMI查询中获取“关联者”结果的问题(无效的变体操作!)

时间:2010-09-05 14:13:52

标签: delphi wmi

我想将this example转换为Delphi代码,我的问题在于获得“Associators of”语句查询的结果:

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;

在标有2星的行中!我收到错误:“ 无效的变体操作 ”,而在上面的相同代码中,不是任何错误!

问题是什么? ,在“协会的声明”或......?!

非常感谢...

2 个答案:

答案 0 :(得分:0)

如果没有看到所有相关的代码和声明,很难说清楚 当你写:

Partitions.Next(1, Partition, IValue);  

你应该在Partition检查你是否真正得到了你想要的东西 更一般地说,要进行调试,您应该始终打破复合语句来测试每个中间步骤:

Partition.Properties_  // is it correct? how many items?
Partition.Properties_.Item('DeviceID', 0) // if not OK try to iterate through all items

答案 1 :(得分:0)

感谢弗朗索瓦......

  

“没有看到所有人就很难说出来   相关的代码和声明。“

但是没有更相关的代码! ,我更改了以下代码:

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;

While 循环中,对于驱动器Enumerate Variant中的每个驱动器,我得到一个“DeviceID”,我应该将“DeviceID”传递给“Associators of”语句以获取与之关联的分区列表作为查询结果由“DeviceID”驱动...

在下一行中,我将分区中的PItems作为IEnumVARIANT,接下来我检查分区中的第一个分区元素是否返回“S_OK”(成功!)然后我检查分区,如果它不是t null then i get one of it s项名为“DeviceID”,但在此行中我收到此消息的错误:“无效的变体操作”

有相同的方法来获取驱动器的DeviceID和分区的DeviceID,但是当我想获得分区的DeviceID时我得到了一个错误,它们和它的WMI查询之间有一个不同,我猜问题是但是我不确定!

有一些有用的句子:

但是,在编写框架提供程序时,请记住以下几点:

* 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. **"**

因为这个解释! ,我认为问题是路径! ,意味着我应该将我的目标(这里是分区)提供给WMIService对象以获得结果! ,there is some help它,但我完全糊涂了!!!!

当然在转换它的Source page中,不是关于路径的任何解释......!

非常感谢...