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
.