Подтвердить что ты не робот

Невозможно прочитать информацию 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://stackoverflow.com/info/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 имеет к этому какое-то отношение.

Есть ли у кого-нибудь представление о возможных причинах такого поведения?

4b9b3361

Ответ 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.