Search code examples
delphidelphi-2010registry

How can a 32-bit program read the "real" 64-bit version of the registry?


I'm trying to read HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run with OpenKeyReadOnly, and GetValueNames, but it's returning values from HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run instead.

How can I read the 64-bit values instead of from a redirect to the 32-bit key?

The program was run as an administrative account. I also tried RegOpenKeyEx and RegEnumValue.

I'm using Delphi 2010.


Solution

  • you must use the KEY_WOW64_64KEY value when open the Registry with the TRegistry class.

    from MSDN :

    KEY_WOW64_64KEY Indicates that an application on 64-bit Windows should operate on the 64-bit registry view. This flag is ignored by 32-bit Windows.

    This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.

    try this sample app.

    {$APPTYPE CONSOLE}
    
    uses
      Windows,
      Classes,
      registry,
      SysUtils;
    
    
    procedure ReadRegistry;
    var
      Registry: TRegistry;
      List    : TStrings;
    begin
      Registry := TRegistry.Create(KEY_WRITE OR KEY_WOW64_64KEY);
      //Registry := TRegistry.Create(KEY_READ OR KEY_WOW64_64KEY);
      List     := TStringList.Create;
      try
        Registry.RootKey := HKEY_LOCAL_MACHINE;
        if Registry.OpenKeyReadOnly('\SOFTWARE\Microsoft\Windows\CurrentVersion\Run') then
        begin
           Registry.GetValueNames(List);
           Writeln(List.Text);
        end;
        Registry.CloseKey;
      finally
        Registry.Free;
        List.Free;
      end;
    end;
    
    begin
      try
       ReadRegistry();
      except
        on E:Exception do
          Writeln(E.Classname, ': ', E.Message);
      end;
      Readln;
    end.