Creating a 32 bit application with delphi I do not have access to all hives depending whether the application is run on a win32 or win64 windows machine. Here is a link for default access: http://msdn.microsoft.com/en-us/library/aa390789(v=VS.85).aspx
I just want to create a single application, and not a separate version for 32 & 64. And I would like to use WMI and retrieve information from the 32 bit registry hive, the 64 bit registry hive and the WOW6432Node. There are FLAGS to set but I can't figure out how to send the flags with a regular WMI query call from my delphi application. Here is info about the FLAGs: 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;
REVISED CODE:
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;
You're using a WMI Moniker and as far as I can see you can't specify the options you need via it. You need to use the SWbemLocator object instead as that let's you pass the SWbemNamedValueSet as the final parameter.
There is a ConnectWMI function in the UProcedures.pas file of GLibWMI. It passes a nil to the final parm:
Services := Locator.ConnectServer(wmiHost,
STR_CIM2_ROOT, {user}STR_EMPTY, {password}STR_EMPTY,
STR_EMPTY,STR_EMPTY, 0, nil);
You need to create an alternative, something like this:
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);
That will get you an ISWbemServices interface on which you can then execute ExecQuery.
Accessing the registry via 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;