17

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.

RRUZ
  • 134,889
  • 20
  • 356
  • 483
Gu.
  • 1,947
  • 4
  • 30
  • 49

1 Answers1

27

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.
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • 2
    AFAIK this example is wrong because OpenKeyReadOnly will reset the Access property to KEY_READ without the KEY_WOW64_64KEY. So you are still reading the 32-bits version. Maybe later Delphi version preserve the KEY_WOW64_64KEY, but I cannot check that. – The_Fox Mar 31 '11 at 06:58
  • Thanks for the answer and for question editing, with English at me are bad while... Has found still: Reg.Access:=KEY_WOW64_64KEY or KEY_ALL_ACCESS; – Gu. Mar 31 '11 at 11:03
  • 2
    @TheFox, I tested the code in delphi 2007 and delphi XE under Windows 7 64 bits, and works ok in both versions. – RRUZ Mar 31 '11 at 13:15
  • 1
    This works, but there is a catch if you want to enumerate the registry recursively. If you pass KEY_WOW64_64KEY and hit one of the Wow6432Node keys (which in regedit is the 32-bit registry) it will instead return the 64-bit base key again, so you can descend indefinitely. The only workaround we've found is to loop up through the key names and revert to 32-bit access if any of the parents is named 'Wow6432Node'. – Zoë Peterson Apr 25 '11 at 15:17
  • 1
    OMG! I found this while posting a question, desperate for help. I had concluded, after a day of debugging, that the same app (Delphi XE5) would WORK as 64-bit, and FAIL as 32-bit. I was going nuts. Very glad to see this here. – Chris Thornton Apr 09 '14 at 21:16
  • 1
    Dang! WOW64 stuff is not available in Delphi2005. Yes, yes, we are upgrading from that. Any workarounds besides hacking our Registry unit? – Chris Thornton Apr 09 '14 at 21:29
  • 1
    FYI, the DXE5 version just needs a few modifications to compile in D2005. Seems to work fine. – Chris Thornton Apr 10 '14 at 14:12