从Delphi访问BcdStore
我正试图将这个代码片段转换成Delphi,我被困在ColoObject中每个objWBL的从Delphi访问BcdStore,delphi,wmi,bcdstore,Delphi,Wmi,Bcdstore,我正试图将这个代码片段转换成Delphi,我被困在ColoObject中每个objWBL的上 if not objBcdStore.EnumerateObjects( &h10200003, colObjects ) then WScript.Echo "ERROR objBcdStore.EnumerateObjects( &h10200003 ) failed." WScript.Quit(1) end if for each objWBL in colOb
上
if not objBcdStore.EnumerateObjects( &h10200003, colObjects ) then
WScript.Echo "ERROR objBcdStore.EnumerateObjects( &h10200003 ) failed."
WScript.Quit(1)
end if
for each objWBL in colObjects
WScript.Echo ""
WScript.Echo "Windows Boot Loader"
WScript.Echo "-------------------"
WScript.Echo "identifier " & GetBcdId( objWBL.Id )
If objWBL.Id = current then
if not objWBL.GetElement(BcdOSLoaderInteger_NumberOfProcessors, objElement ) then
WScript.Echo "ERROR WBL GetElement for " & Hex(BcdOSLoaderInteger_NumberOfProcessors) & " failed."
WScript.Quit(1)
end if
WScript.Echo "numproc " & objElement.Integer
if not objWBL.GetElement(BcdOSLoaderBoolean_UseBootProcessorOnly, objElement ) then
WScript.Echo "ERROR WBL GetElement for " & Hex(BcdOSLoaderBoolean_UseBootProcessorOnly) & " failed."
WScript.Quit(1)
end if
WScript.Echo "onecpu " & objElement.Boolean
end if
next
我的部分q&d翻译(注意,必须是管理员才能运行):
定义为
boolean EnumerateObjects(
[in] uint32 Type,
[out] BcdObject Objects[]
);
我不知道如何在Delphi中遍历BcdObject数组。您必须使用and函数来获取由EnumerateObjects
函数返回的变量数组的边界,然后您可以使用for
循环来迭代数组的元素
检查一下这个样品
Uses
ComObj,
ActiveX;
function GetObject(const objectName: String): IDispatch;
var
bindCtx: IBindCtx;
moniker: IMoniker;
chEaten: Integer;
begin
OleCheck(CreateBindCtx(0, bindCtx));
OleCheck(MkParseDisplayName(bindCtx, StringToOleStr(objectName), chEaten, moniker));
OleCheck(moniker.BindToObject(bindCtx, nil, IDispatch, Result));
end;
procedure TForm44.Button1Click(Sender: TObject);
var
colObjects : OleVariant;
objBcdStore : OleVariant;
objWMIService: OleVariant;
i : Integer;
objWBL : OleVariant;
begin
objWMIService := GetObject('winmgmts:{impersonationlevel=Impersonate,(Backup,Restore)}!root/wmi:BcdStore');
if not objWMIService.OpenStore('', objBcdStore) then
Caption := 'error'
else
begin
objBcdStore.EnumerateObjects($10200003, colObjects);
if not VarIsNull(colObjects) and VarIsArray(colObjects) then
for i := VarArrayLowBound(colObjects, 1) to VarArrayHighBound(colObjects, 1) do
begin
objWBL:=colObjects[i];
//do your stuff here
end;
end;
end;
感谢RRUZ的回答——我学到了一些新的东西——但遗憾的是,正确的答案是“不要那样做”(多么典型!)
事实证明,通过枚举Windows引导加载程序对象,我们无法找出哪些对象是“当前”对象。正如我最终发现的(多亏了2008年7月发行的TechNet杂志上的文章),正确的方法是直接通过它的已知ID打开loader对象(这也是一个隐藏得很好但并不广为人知的方法。我在著名的BCD GUI上找到的唯一官方文档是document)
下面的示例代码首先打开BCD WMI对象。然后,它打开默认存储并显示{current}
引导条目对象的信息(由已知ID访问)
接下来,它打开Windows引导管理器
对象(通过使用其已知ID),读取其DefaultObject
元素以确定默认引导项的GUID,根据其GUID打开此对象并显示信息
ShowLoaderInfo
仅显示ID
(GUID)、Description
和NumberOfProcessors
(这是我想从BCD获得的信息)。这里有一个有趣的技巧,后者是bcdintegreement
类型,它通过Integer属性返回其值,具有一个“特性”,即返回的值不是整数而是字符串。报告中的说明解释了:
元素的整数值。该值作为字符串传递
因为自动化本身不支持64位整数
(是的,太棒了!为什么它必须是64位的?20亿处理器还不够吗?)
有关受支持的Windows引导加载程序元素的完整列表,请参阅
我想你试过“for x in y do z()”语法,但没有成功?事实上,我没有。但是,它不起作用:“[DCC Error]Unit44.pas(55):E2430 for in语句不能对集合类型'OleVariant'进行操作。”我认为OleVariant数组和for in都不起作用,但我只是想知道。
Uses
ComObj,
ActiveX;
function GetObject(const objectName: String): IDispatch;
var
bindCtx: IBindCtx;
moniker: IMoniker;
chEaten: Integer;
begin
OleCheck(CreateBindCtx(0, bindCtx));
OleCheck(MkParseDisplayName(bindCtx, StringToOleStr(objectName), chEaten, moniker));
OleCheck(moniker.BindToObject(bindCtx, nil, IDispatch, Result));
end;
procedure TForm44.Button1Click(Sender: TObject);
var
colObjects : OleVariant;
objBcdStore : OleVariant;
objWMIService: OleVariant;
i : Integer;
objWBL : OleVariant;
begin
objWMIService := GetObject('winmgmts:{impersonationlevel=Impersonate,(Backup,Restore)}!root/wmi:BcdStore');
if not objWMIService.OpenStore('', objBcdStore) then
Caption := 'error'
else
begin
objBcdStore.EnumerateObjects($10200003, colObjects);
if not VarIsNull(colObjects) and VarIsArray(colObjects) then
for i := VarArrayLowBound(colObjects, 1) to VarArrayHighBound(colObjects, 1) do
begin
objWBL:=colObjects[i];
//do your stuff here
end;
end;
end;
program ShowBCDInfo;
{$APPTYPE CONSOLE}
uses
SysUtils,
ComObj,
ActiveX;
const
Description = $12000004; //http://msdn.microsoft.com/en-us/aa362652(v=VS.85)
UseBootProcessorOnly = $26000060; //http://msdn.microsoft.com/en-us/aa362641(v=VS.85)
NumberOfProcessors = $25000061;
ForceMaximumProcessors = $26000062;
ProcessorConfigurationFlags = $25000063;
DefaultObject = $23000003; //http://msdn.microsoft.com/en-us/aa362641(v=VS.85)
CurrentGUID = '{fa926493-6f1c-4193-a414-58f0b2456d1e}'; //http://msdn.microsoft.com/en-us/windows/hardware/gg463059.aspx
WBMGUID = '{9dea862c-5cdd-4e70-acc1-f32b344d4795}';
function GetObject(const objectName: String): IDispatch;
var
bindCtx: IBindCtx;
moniker: IMoniker;
chEaten: Integer;
begin
OleCheck(CreateBindCtx(0, bindCtx));
OleCheck(MkParseDisplayName(bindCtx, StringToOleStr(objectName), chEaten, moniker));
OleCheck(moniker.BindToObject(bindCtx, nil, IDispatch, Result));
end;
procedure ShowLoaderInfo(const name: string; const obj: OleVariant);
var
objElement: OleVariant;
begin
Writeln(Format('%s ID: %s', [name, string(obj.id)]));
if obj.GetElement(Description, objElement) then
Writeln(Format('Description: %s', [objElement.String]));
if obj.GetElement(NumberOfProcessors, objElement) then
Writeln(Format('NumProc: %s', [objElement.Integer]));
end;
procedure ShowBcdInfo;
var
objBcdStore : OleVariant;
objWBL : OleVariant;
objWBM : OleVariant;
objWMIService: OleVariant;
begin
objWMIService := GetObject('winmgmts:{(Backup,Restore)}\\.\root\wmi:BcdStore');
if not objWMIService.OpenStore('', objBcdStore) then
Writeln('*** error opening store')
else begin
if objBcdStore.OpenObject(CurrentGUID, objWBL) then
ShowLoaderInfo('{current}', objWBL);
if objBcdStore.OpenObject(WBMGuid, objWBM) and
objWBM.GetElement(DefaultObject, objWBL) and
objBcdStore.OpenObject(string(objWBL.ID), objWBL)
then
ShowLoaderInfo('{default}', objWBL);
end;
end;
begin
try
OleInitialize(nil);
try
ShowBCDInfo;
finally OleUninitialize; end;
Readln;
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
end.