访问注册表中的所有3个配置单元

时间:2010-12-19 14:58:26

标签: delphi registry wmi wow64

使用delphi创建32位应用程序我无法访问所有配置单元,具体取决于应用程序是在win32还是win64 windows机器上运行。以下是默认访问的链接:http://msdn.microsoft.com/en-us/library/aa390789(v=VS.85).aspx

我只是想创建一个单独的应用程序,而不是32&的单独版本。 64.我想使用WMI并从32位注册表配置单元,64位注册表配置单元和WOW6432Node中检索信息。有FLAGS设置,但我无法弄清楚如何从我的delphi应用程序发送常规WMI查询调用标志。以下是有关FLAG的信息:http://msdn.microsoft.com/en-us/library/aa393067(v=VS.85).aspx

GLibWmi& DelphiWmiCodeCreator例子:

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;

1 个答案:

答案 0 :(得分:2)

您正在使用WMI Moniker,据我所知,您无法通过它指定所需的选项。您需要使用SWbemLocator对象,因为您可以将SWbemNamedValueSet作为最终参数传递。

GLibWMI的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接口,然后您可以在其上执行ExecQuery。

通过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;