2010-09-05 11 views
2

Je veux convertir this example au code Delphi, Mon problème est d'obtenir la suite de « associateurs de » requête de déclaration:problème à obtenir Résultat de « associateurs de » Déclaration de requête 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; 

Dans la ligne marquée avec 2 étoiles! J'ai une erreur: "Opération de variante invalide" alors que dans le dessus de celui-ci dans le même code, il n'y a aucune erreur!

Quel est le problème? , dans la déclaration "Associators of" ou ...?!

merci beaucoup ...

Répondre

0

Difficile à dire sans voir tout le code et déclarations pertinentes.
Lorsque vous écrivez:

Partitions.Next(1, Partition, IValue); 

Vous devez vérifier que vous obtenez en fait ce que vous voulez Partition.
Et plus généralement, de débogage, vous devez toujours casser votre déclaration de composé à tester chaque étape intermédiaire:

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

grâce à François ...

« Difficile à dire sans voir tous les code et déclarations pertinents. "

Mais il n'y a plus de code pertinent! , J'ai changé le code suivant:

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; 

Dans la While, pour chaque disque dans les lecteurs Énumérer Variant, je reçois un « DeviceID », je devrais passer « DeviceID » à « associateurs de » déclaration à obtenir la liste de Partition Associated avec Drive par "DeviceID" à la suite de la requête ...

Dans la ligne suivante, je place les PItems dans les partitions comme un IEnumVARIANT, je vérifie ensuite si le premier élément des Partitions dans la partition est retourné "S_OK" (avec succès!) Puis je vérifie Partition et si ce n'est t null then i get one of it s éléments nommés "DeviceID", mais dans cette ligne, je reçois une erreur avec ce message: "Invalid Va Opération riant "

il ya des façons d'obtenir DeviceID de Drive et DeviceID de Partition, mais quand je veux obtenir DeviceID de Partition j'ai eu une erreur, il y a un différent entre eux et c'est la requête de WMI, je suppose le problème est mais je ne suis pas sûr!

il y a quelques phrases utiles:

" Cependant, vous devez garder ceci à l'esprit lors de l'écriture de votre fournisseur de cadre:

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

à cause de ce qui explique, je pense que le problème est le chemin!, signifie que je devrais donner ma cible (voici Partition) à l'objet WMIService pour obtenir les résultats!, there is some help de celui-ci, mais je suis totalement confus !!!!

Bien sûr, dans le Source page que je le convertis, il n'y a pas d'explication sur le chemin ...!

merci beaucoup ...