Trouble with TRegistry [Solved on WinApi] lazarus / 34-Windows ---------------------------------------------------------------------- CynicRus · 2015-08-11 19:09 Hi all. I have a kind of problem with TRegistry.GetKeyNames. I declare the registry key as const: Code: [Select]const MyKey = '\SOFTWARE\Microsoft\Windows Portable Devices\Devices'; After than I try to read the subkey names of this key: Code: [Select]    var       Str: TStringList;       Reg: TRegistry;     begin       Str := TStringList.Create;       Reg := TRegistry.Create;       Reg.RootKey:=HKEY_LOCAL_MACHINE;       try         if Reg.OpenKeyReadOnly(MyKey) then         begin           Reg.GetKeyNames(Str);           Str.SaveToFile('C:\Devices.txt');         end;       finally         Reg.CloseKey;         Str.Free;       end;     end; But I always got Str.Count = 0, but though regedit I see all subkeys. What I do wrong? Thank you. PS: Win7 x64 Ultimate + Lazarus 1.0.14 + FPC 2.6.2. ---------------------------------------------------------------------- derek.john.evans · 2015-08-11 19:59 Code looks fine. Worked here with a key from my registry. Maybe check your user permissions. ---------------------------------------------------------------------- CynicRus · 2015-08-11 20:05 Quote from: derek.john.evans on August 11, 2015, 09:59:15 pmCode looks fine. Worked here with a key from my registry. Maybe check your user permissions. Hm. Weird. I run that code as administrator an that doesn't work:( ---------------------------------------------------------------------- derek.john.evans · 2015-08-11 20:14 Try a different key, or  HKEY. Make sure you are coping the key name using regedit. Dont rely on eye sight. Something should work. And then backtrack until you find the issue. ** EDIT ** Check the permissions for HKEY_LOCAL_MACHINE. They might not have read access ---------------------------------------------------------------------- rvk · 2015-08-11 20:20 Yeah, you jumped right in the SysWOW64 trap (It's not a permission problem) Just like the system32-directory (for 64bit dll's) under Windows-dir is separated from the SysWOW64-directory (for 32dll's) so is the registry also separated. You are essentially looking at this key with your 32bit program: Code: [Select]HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Portable Devices\Devices (without you knowing it ) When you want to access the 64bit tree from a 32bit program you need to specify the KEY_WOW64_64KEY flag for access. Code: [Select]var   Str: TStringList;   Reg: TRegistry; begin   Str := TStringList.Create;   Reg := TRegistry.Create;   Reg.RootKey := HKEY_LOCAL_MACHINE;   Reg.Access := KEY_READ or KEY_WOW64_64KEY;   try     if Reg.OpenKeyReadOnly(MyKey) then     begin       Reg.GetKeyNames(Str);       ShowMessage(Str.Text);       Str.SaveToFile('C:\temp\Devices.txt');     end;   finally     Reg.CloseKey;     Str.Free;   end; B.T.W I wouldn't save to C:\ because that is often restricted. Use C:\Temp or something else. ---------------------------------------------------------------------- CynicRus · 2015-08-12 06:29 Weird, but Code: [Select]Reg:= TRegistry.Create;   try      Reg.RootKey := HKEY_LOCAL_MACHINE;      Reg.Access := KEY_READ or KEY_WOW64_64KEY; doesn't help. Still Str>count = 0. But registry have the information: (http://f6.s.qip.ru/w5qyEBdB.png) ---------------------------------------------------------------------- CynicRus · 2015-08-12 08:38 Heh. I've solved that problem on WinApi: Code: [Select]function GetSubkeys(MainKey: LongInt; aKey: string;var aList: TStringList): Boolean; var   hRoot: HKEY;   lItem: LongInt;   hError: LongInt;   szKey, pData: PChar;   aString: string; begin   Result := false;   if aList = nil then     exit;   szKey := StrAlloc(Length(aKey) + 1);   StrPCopy(szKey, aKey);   lItem := 0;   pData := StrAlloc(1024);   hError := RegOpenKeyEx(MainKey, szKey, 0, Key_Read or KEY_WOW64_64KEY, hRoot);   if hError = ERROR_SUCCESS then   begin     while (hError = ERROR_SUCCESS) do     begin       hError := RegEnumKey(hRoot, lItem, pData, 1024);       if (hError = ERROR_SUCCESS) then       begin         Result  := true;         aList.Add(StrPas(pData));         Inc(lItem);       end;     end;     RegCloseKey(hRoot);   end;   StrDispose(szKey);   StrDispose(pData); end; But I still don't understand, why I can't doing the same operation with TRegistry ---------------------------------------------------------------------- marcov · 2015-08-12 10:56 try reg.access:=reg.access or KEY_WOW64_64KEY; ---------------------------------------------------------------------- CynicRus · 2015-08-12 11:28 Quote from: marcov on August 12, 2015, 12:56:01 pmtry reg.access:=reg.access or KEY_WOW64_64KEY; Didn't work for me:( ---------------------------------------------------------------------- rvk · 2015-08-12 11:29 Quote from: CynicRus on August 11, 2015, 09:09:34 pmPS: Win7 x64 Ultimate + Lazarus 1.0.14 + FPC 2.6.2. O, wow. What is the reason you're still working with an old version of Lazarus and FPC ??? The problem you're having lies in the fact that FPC 2.6.2 has this as OpenKeyReadOnly: Code: [Select]function TRegistry.OpenKeyReadOnly(const Key: string): Boolean; Var   P: PChar;   Handle: HKEY; begin   P:=PrepKey(Key);   Result := RegOpenKeyExA(GetBaseKey(RelativeKey(Key)),P,0,KEY_READ,Handle) = 0;   If Result Then     fCurrentKey := Handle; end; You see that the flag KEY_READ is hardcoded and putting KEY_WOW64_64KEY in the access-property doesn't help much. If you look at the FPC 2.6.4 implementation: Code: [Select]function TRegistry.OpenKeyReadOnly(const Key: string): Boolean; Var   OldAccess: LongWord; begin   OldAccess:=fAccess;   fAccess:=KEY_READ {$ifndef WinCE} or (OldAccess and (KEY_WOW64_64KEY or KEY_WOW64_32KEY)) {$endif};   try     Result:=OpenKey(Key, False);   finally     fAccess:=OldAccess;   end; end; You'll see it checks fAccess (OldAccess) if you have given the KEY_WOW64_64KEY flag. So you need to upgrade to FPC 2.6.4 or use your WinApi-solution. (or patch winreg.inc yourself) ---------------------------------------------------------------------- CynicRus · 2015-08-12 11:40 Ah! Thank you!