Delphi 获取WMI查询中“Associators of”语句的结果时出现问题(变量操作无效!)

Delphi 获取WMI查询中“Associators of”语句的结果时出现问题(变量操作无效!),delphi,wmi,Delphi,Wmi,我想转换成Delphi代码,我的问题是如何获得语句查询关联器的结果: procedure TUSB.GetInfo; var WMIService : OLEVariant; DItems, PItems, LItems, VItems: OLEVariant; Drive, Partition, Logical, Volume : OLEVariant; Drives, Partitions, Logicals, Volumes : IEnumVARIANT; IValue : Lo

我想转换成Delphi代码,我的问题是如何获得语句查询关联器的结果:

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颗星的直线上!我得到一个错误:无效的变量操作,而在上面的它在同一个代码中,是没有任何错误

有什么问题吗,在声明的关联中或


非常感谢……

如果没有看到所有相关的代码和声明,很难判断。 当你写作时:

Partitions.Next(1, Partition, IValue);  
您应该检查您是否确实在分区中得到了所需的内容。 更一般地说,要进行调试,您应该始终中断复合语句以测试每个中间步骤:

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

如果看不到所有相关的代码和声明,就很难判断。 当你写作时:

Partitions.Next(1, Partition, IValue);  
您应该检查您是否确实在分区中得到了所需的内容。 更一般地说,要进行调试,您应该始终中断复合语句以测试每个中间步骤:

Partition.Properties_  // is it correct? how many items?
Partition.Properties_.Item('DeviceID', 0) // if not OK try to iterate through all items
多亏了弗朗索瓦


看不见就很难说 有关守则及声明

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

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循环中,对于Drives-In-Drives-Enumerate变量,我获得一个DeviceID,我应该将DeviceID传递给语句的Associators,以获得作为查询结果的与Drive-by-DeviceID关联的分区列表

在下一行中,我将PItems作为IEnumVARIANT放在分区中,接下来我检查将分区的第一个元素放在分区中是否成功返回S_OK!然后我检查分区,如果它不是空的,那么我会得到它的一个名为DeviceID的项,但在这一行中,我得到一个错误消息:Variant Operation无效

获取驱动器的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对象以获得结果,当然,但我完全糊涂了

当然,在我转换它的过程中,没有任何关于路径的解释

非常感谢……

感谢弗朗索瓦


看不见就很难说 有关守则及声明

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

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循环中,对于Drives-In-Drives-Enumerate变量,我获得一个DeviceID,我应该将DeviceID传递给语句的Associators,以获得作为查询结果的与Drive-by-DeviceID关联的分区列表

在下一行中,我将PItems作为IEnumVARIANT放在分区中,接下来我检查将分区的第一个元素放在分区中是否成功返回S_OK!然后我检查分区,如果它不是空的,那么我会得到它的一个名为DeviceID的项,但在这一行中,我得到一个错误消息:Variant Operation无效

获取驱动器的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对象以获得结果,当然,但我完全糊涂了

当然,在我转换它的过程中,没有任何关于路径的解释

非常感谢