2010-09-05 47 views
2

我想转换this example德尔福代码,我的问题是获得的声明中查询“的社员”的结果:问题在得到声明“社员”结果在WMI查询

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星的行中!我得到一个错误:“无效的变式操作”而在上面的相同的代码中,没有任何错误!

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

非常感谢......

回答

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 
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; 

虽然循环,在驱动器枚举变型,各驱动器,我得到一个“的DeviceID”,我应该通过“的DeviceID”陈述“的社员”到作为查询的结果获得与驱动器相关联的分区列表“DeviceID”...

在下一行中,我把PItems分区作为IEnumVARIANT,接下来我检查是否将分区的第一个元素放入分区“S_OK”(成功!)然后我检查分区,如果它不是名为“DeviceID”的项目,但在这一行中,我收到一条错误消息:“无效的Va riant操作“

有相同的方式来获取驱动器的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

当然,我将其转换,isn`t任何关于路径解释...!

非常感谢...