Impossible de lire les informations BCDStore sur Windows 2012 Server à l’aide de WMI

Nous utilisons la fonction suivante pour obtenir le nombre de processeurs spécifié par la configuration de démarrage actuelle. Ce numéro est utilisé uniquement pour la journalisation.

La fonction ci-dessous fonctionne correctement sous XP, Vista, 7, 2003 et 2008. Elle échoue toutefois sur le serveur Windows 2012.

// -1 = not implemented or not allowed // 0 = not limited // >0 = number of processors in the {current} boot entry function Internal_GetBCDNumberOfProcessors: integer; var objBcdStore : OleVariant; objElement : OleVariant; objWBL : OleVariant; objWMIService: OleVariant; begin // for more info, see: http://stackoverflow.com/questions/7517965/accessing-bcdstore-from-delphi/7527164#7527164 Result := -1; try objWMIService := GetObject('winmgmts:{(Backup,Restore)}\\.\root\wmi:BcdStore'); if (not VarIsNull(objWMIService)) and boolean(objWMIService.OpenStore('', objBcdStore)) and (not VarIsNull(objBcdStore)) and boolean(objBcdStore.OpenObject('{fa926493-6f1c-4193-a414-58f0b2456d1e}', objWBL)) and (not VarIsNull(objWBL)) then if objWBL.GetElement($25000061, objElement) and //<-- fails here on Server 2012 (not VarIsNull(objElement)) then Result := StrToIntDef(objElement.Integer, 0) else Result := 0; except on E: EOleSysError do Result := -1; end; end; 

Si j’essaie de l’exécuter sur Win2012, le objWBL.GetElement déclenche EOleSysError exception EOleSysError avec le texte d’ OLE error D0000225 . Google ne trouve rien de significatif lié à ce code d’erreur 🙁

La trace de stack indique que l’exception est déclenchée dans System.Win.ComObj.DispatchInvokeError, appelé par DispatchInvoke appelé par VarDispInvoke.

Tout cela a été reproduit en utilisant XE2. Je pourrais essayer de répéter le problème avec XE3 mais je ne pense pas que Delphi RTL y soit pour quelque chose.

Quelqu’un a-t-il une idée des raisons possibles de ce comportement?

La partie GetElement :

 if objWBL.GetElement($25000061, objElement) and //<-- fails here on Server 2012 (not VarIsNull(objElement)) then Result := StrToIntDef(objElement.Integer, 0) else Result := 0; 

peut être remplacé par EnumerateElements :

 if objWBL.EnumerateElements(objArray) then try for i := VarArrayLowBound(objArray, 1) to VarArrayHighBound(objArray, 1) do begin objElement := objArray[i]; if objElement.Type = $25000061 then Exit(objElement.Integer); end; finally VarClear(objArray); end; 

Cela ne EOleException pas l' EOleException , mais malheureusement, ne trouve pas non plus l'élément NumberOfProcessors .