题
使用Delphi创建32位应用程序,我无法访问所有蜂箱,具体取决于该应用程序是在Win32还是Win64 Windows机器上运行的。这是用于默认访问的链接: http://msdn.microsoft.com/en-us/library/aa390789(v=vs.85).aspx
我只想创建一个单个应用程序,而不是32&64的单独版本。我想使用WMI并从32位注册表中检索信息,而64位注册表Hive和WOW6432Node。有标志要设置,但我不知道如何通过我的Delphi应用程序从常规的WMI查询调用发送标志。这是有关标志的信息: http://msdn.microsoft.com/en-us/library/aa393067(v=vs.85).aspx
Glibwmi和Delphiwmicodecreator Exmple:
function GetWMIObject(const objectName: String): IDispatch; //create the Wmi instance
var
chEaten: Integer;
BindCtx: IBindCtx;
Moniker: IMoniker;
begin
OleCheck(CreateBindCtx(0, bindCtx));
OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker));
OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
end;
procedure GetWin32_StartupCommandInfo;
var
objWMIService : OLEVariant;
colItems : OLEVariant;
colItem : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
begin;
objWMIService := GetWMIObject('winmgmts:\\localhost\root\CIMV2');
colItems := objWMIService.ExecQuery('SELECT * FROM Win32_StartupCommand','WQL',0);
oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
while oEnum.Next(1, colItem, iValue) = 0 do
begin
Writeln('');
end;
end;
修订代码:
procedure GetWin32_StartupCommandInfo(aIDispatch: IDispatch);
var
objWMIService : OLEVariant;
colItems : OLEVariant;
colItem : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
begin;
objWMIService := aIDispatch; //GetWMIObject('winmgmts:\\localhost\root\CIMV2');
colItems := objWMIService.ExecQuery('SELECT * FROM Win32_StartupCommand','WQL',0);
oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
while oEnum.Next(1, colItem, iValue) = 0 do
begin
with Form1.lst1 do begin
items.Add(Format('Caption="%s"; Location="%s"',[colItem.Caption,colItem.Location]));// String
{items.Add(Format('Command %s',[colItem.Command]));// String
items.Add(Format('Description %s',[colItem.Description]));// String
items.Add(Format('Location %s',[colItem.Location]));// String
items.Add(Format('Name %s',[colItem.Name]));// String
items.Add(Format('SettingID %s',[colItem.SettingID]));// String
items.Add(Format('User %s',[colItem.User]));// String
items.Add(Format('UserSID %s',[colItem.UserSID]));// String
}
items.Add('');
end;
end;
end;
function MyConnectWMI(wmiHost:string; var Services: ISWbemServices):Boolean;
const
STR_CIM2_ROOT ='root\CIMV2';
STR_EMPTY = '';
var
NVS: SWbemNamedValueSet;
providerArchitecture : OleVariant;
requiredArchitecture : OleVariant;
Locator : ISWbemLocator; //CoSWbemLocator;
begin
try
providerArchitecture := 32; // or 64
requiredArchitecture := true;
NVS := CoSWbemNamedValueSet.Create( );
NVS.Add('__ProviderArchitecture', providerArchitecture , 0);
NVS.Add('__RequiredArchitecture', requiredArchitecture , 0);
// Create the Location object
Locator := CoSWbemLocator.Create();
// Connect to the WMI service, with the root\cimv2 namespace
Services := Locator.ConnectServer(wmiHost,
STR_CIM2_ROOT, {user}STR_EMPTY, {password}STR_EMPTY,
STR_EMPTY,STR_EMPTY, 0, NVS);
Result := True;
except
Result := False;
end;
end;
procedure TForm1.btn1Click(Sender: TObject);
var
aServices: ISWbemServices;
begin
if MyConnectWMI('localhost', aServices) then
GetWin32_StartupCommandInfo(aServices);
end;
解决方案
您正在使用WMI绰号,据我所知,您无法通过它指定所需的选项。您需要使用swbemlocator对象,因为它可以通过SwbemnamedValueset作为最终参数。
uprocedures.pas文件中有一个connectwmi函数。它通过一个零进入了最后的parm:
Services := Locator.ConnectServer(wmiHost,
STR_CIM2_ROOT, {user}STR_EMPTY, {password}STR_EMPTY,
STR_EMPTY,STR_EMPTY, 0, nil);
您需要创建一个替代方案,类似的东西:
var
NVS: SWbemNamedValueSet;
providerArchitecture : OleVariant;
requiredArchitecture : OleVariant;
/////
providerArchitecture := 32; // or 64
requiredArchitecture := true;
NVS := CoSWbemNamedValueSet.Create();
NVS.Add('__ProviderArchitecture', providerArchitecture , 0);
NVS.Add('__RequiredArchitecture', requiredArchitecture , 0);
// Create the Location object
Locator := CoSWbemLocator.Create();
// Connect to the WMI service, with the root\cimv2 namespace
Services := Locator.ConnectServer(wmiHost,
STR_CIM2_ROOT, {user}STR_EMPTY, {password}STR_EMPTY,
STR_EMPTY,STR_EMPTY, 0, NVS);
这将使您获得ISWBEMServices接口,然后您可以在该接口上执行执行。
通过STDREGPROV访问注册表 -
procedure Get_RegistryValue(aIDispatch: IDispatch);
var
objWMIService : OLEVariant;
strKeyPath : OLEVariant;
strValue : OLEVariant;
strOut : OLEVariant;
objStdRegProv : OLEVariant;
begin;
objWMIService := aIDispatch;
objStdRegProv := objWMIService.Get('StdRegProv');
strKeyPath := 'Software\Microsoft\Wbem\CIMOM';
strValue := 'Logging';
objStdRegProv.GetStringValue(HKEY_LOCAL_MACHINE, strKeyPath, strValue, strOut);
with Form1.lst1 do begin
items.Add(strOut);
end;
end;
end;
// connect to root\default instead of cimv2
function MyConnectWMI(wmiHost:string; var Services: ISWbemServices):Boolean;
const
STR_DEFAULT_ROOT = 'root\default'
STR_EMPTY = '';
var
NVS: SWbemNamedValueSet;
providerArchitecture : OleVariant;
requiredArchitecture : OleVariant;
Locator : ISWbemLocator; //CoSWbemLocator;
begin
try
providerArchitecture := 32; // or 64
requiredArchitecture := true;
NVS := CoSWbemNamedValueSet.Create( );
NVS.Add('__ProviderArchitecture', providerArchitecture , 0);
NVS.Add('__RequiredArchitecture', requiredArchitecture , 0);
// Create the Location object
Locator := CoSWbemLocator.Create();
// Connect to the WMI service, with the root\cimv2 namespace
Services := Locator.ConnectServer(wmiHost,
STR_DEFAULT_ROOT, {user}STR_EMPTY, {password}STR_EMPTY,
STR_EMPTY,STR_EMPTY, 0, NVS);
Result := True;
except
Result := False;
end;
end;
不隶属于 StackOverflow