无法使用 WMI 在 Windows 2012 Server 上读取 BCDStore 信息
Posted
技术标签:
【中文标题】无法使用 WMI 在 Windows 2012 Server 上读取 BCDStore 信息【英文标题】:Cannot read BCDStore info on Windows 2012 Server using WMI 【发布时间】:2012-12-19 00:03:30 【问题描述】:我们正在使用以下函数来获取当前引导配置指定的处理器数量。这个数字纯粹用于记录。
以下功能在 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://***.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
。谷歌没有找到与此错误代码相关的任何有意义的东西:(
堆栈跟踪表明异常是在由 VarDispInvoke 调用的 DispatchInvoke 调用的 System.Win.ComObj.DispatchInvokeError 中触发的。
所有这些都是使用 XE2 复制的。我可以尝试用 XE3 重复这个问题,但我不相信 Delphi RTL 与它有任何关系。
有人知道这种行为的可能原因吗?
【问题讨论】:
你有更新 4 修补程序 1 吗? 是的,我应该有。我会仔细检查。 (Exe 是在构建服务器上构建的,应该安装了 U4H1。) UAC 开启还是关闭?进程提升还是不提升? UAC 打开,作为服务和提升的 GUI 进程进行测试。没有区别。 你可以尝试使用VbScript来获取错误描述,试试这个示例pastebin.com/ALmnk4R0 【参考方案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
元素。
【讨论】:
以上是关于无法使用 WMI 在 Windows 2012 Server 上读取 BCDStore 信息的主要内容,如果未能解决你的问题,请参考以下文章