Невозможно прочитать информацию BCDStore на Windows 2012 Server с помощью WMI
Мы используем следующую функцию, чтобы получить число процессоров, указанное в текущей конфигурации загрузки. Этот номер используется исключительно для регистрации.
Приведенная ниже функция отлично работает на XP, Vista, 7, 2003 и 2008. Однако она не работает на Windows 2012 Server.
// -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://stackru.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;
Если я попытаюсь запустить его на Win2012, objWBL.GetElement
повышения EOleSysError
исключение с текстом OLE error D0000225
, Google не находит ничего значимого, связанного с этим кодом ошибки:(
Трассировка стека говорит, что исключение вызвано в System.Win.ComObj.DispatchInvokeError, которая вызывается DispatchInvoke, который вызывается VarDispInvoke.
Все это было воспроизведено с использованием XE2. Я мог бы попытаться повторить проблему с XE3, но я не верю, что Delphi RTL имеет к этому какое-либо отношение.
Кто-нибудь имеет представление о возможных причинах такого поведения?
1 ответ
GetElement
часть:
if objWBL.GetElement($25000061, objElement) and //<-- fails here on Server 2012
(not VarIsNull(objElement))
then
Result := StrToIntDef(objElement.Integer, 0)
else
Result := 0;
можно заменить на 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;
Это не поднимает EOleException
но, к сожалению, также не находит NumberOfProcessors
элемент.