TRegistry.ReadString returns empty string on Win64, not Win32 lazarus / 34-Windows ---------------------------------------------------------------------- ffejrobins30 · 2011-02-10 07:06 I've got a problem with the following code: Code: [Select]procedure TForm1.GetMachineGUID(); var   fReg:TRegistry;   GUIDStr:String; begin   try      fReg:=Tregistry.Create;      fReg.RootKey:=HKEY_LOCAL_MACHINE;      if fReg.OpenKey('\SOFTWARE\Microsoft\Cryptography', false) then        begin           GUIDStr:=freg.ReadString('MachineGuid');           ShowMessage(GUIDStr);        end;    finally     fReg.Free;   end; end; If I compile this under the 32-bit version of Lazarus/FPC then it works fine on 32-bit windows machines, but TRegistry.ReadString returns an empty string when run in 64-bit Windows. If I compile it under 64-bit Lazarus/FPC, then it returns the correct string when run in 64-bit windows. This is with no code difference between the two versions, just a different compiler. Is there something wrong with the code, or is it a bug? I know 100% that the Key exists in the same path on both 32 and 64-bit windows environments. I am running Windows 7 Ultimate 32-bit Lazarus ver 0.9.31 FPC ver 2.4.3 SVN 29435 ---------------------------------------------------------------------- marcov · 2011-02-10 10:16 Probably this setting is for the native platform (iow 32-bit on 32-bit windows, and 64-bit on 64-bit windows), and for the 32-bit exe on 64-bit windows you need to do something special. Some 32-bit subsystems on 64-bit windows are in different placed which is managed by WoW64 (windows on windows emulation, the name for the 32-bit layer of 64-bit windows) Probably you have to test for this in the 32-bit binary (ifdef!) using the IsWow64Process function, and then specify the alternate registry location where the 32-bit versions are kept on win64. Such duplicate situations (one for 32-bit one for 64-bit) are typical when the settings also contain references to DLLs, which must be 32-bit or 64-bit. ---------------------------------------------------------------------- ffejrobins30 · 2011-02-19 21:49 Thanks for the reply. This was he probem. What I found was that 32-Bit apps are run on a "Virtual Machine" aka Windows on Windows Emulation and the VM doesn't have a Local machine Globally Unique ID. There is no alternate path for this, so I actually have to build a 32 and 64 bit app if I want to continue using this registry entry. ---------------------------------------------------------------------- dieselnutjob · 2011-03-29 12:28 just in case anyone else stumbles across the above code (first google hits for freepascal SOFTWARE\Microsoft\Cryptography ) the code only works if the user running it has admin rights if you use OpenKeyReadOnly like this:- Code: [Select]procedure TForm1.GetMachineGUID(); var   fReg:TRegistry;   GUIDStr:String; begin   try      fReg:=Tregistry.Create;      fReg.RootKey:=HKEY_LOCAL_MACHINE;      if fReg.OpenKeyReadOnly('\SOFTWARE\Microsoft\Cryptography') then        begin           GUIDStr:=freg.ReadString('MachineGuid');           ShowMessage(GUIDStr);        end;   finally     fReg.Free;   end; end;  then it gives the GUID even if the user doesn't have admin rights. ---------------------------------------------------------------------- IPguy · 2011-11-13 01:58 I'm running into the same issue. I've created a very simple Win-32 program that does a read-only (dieselnutjob, thanks for your hint) of the same key as ffejrobins30 used. On my Vista-32, N2K VM, Vista-32 VM, Win7-32 VM - I get the expected GUID. When I run this on my Win7-64 system (real machine, not a VM), I get an empty string. I have verified that the regedit path and parameter name are identical. 0.9.31-33481-2.5-1-win32, on a Win7-64 system ---------------------------------------------------------------------- IPguy · 2011-11-13 02:31 Still snooping, but it appears that the 64 systems handle the registry differently than the 32 bit systems.  This is from an article I found on the topic: http://www.codeproject.com/KB/system/Reflection.aspx Still not making sense yet.  Not sure how to use "KEY_WOW64_32KEY". QuoteThere a new flags which can be used to access the alternate registry view in your 32-bit or 64-bit application. With this flag, you can force RegCreateKeyEx, RegDeleteKeyEx and RegOpenKeyEx to explicitly access the 64-bit view (KEY_WOW64_64KEY) or the 32-bit (KEY_WOW64_32KEY) view of the registry, independent of your process' default view. Of course, this only makes sense if you access some keys which will be redirected. ---------------------------------------------------------------------- IPguy · 2011-11-13 02:50 If you want to run your 32-bit app on a 64-bit machine and extract info from the Windows Registry, modify the following line: Code: [Select]from:  fReg:=Tregistry.Create; to:      fReg:=Tregistry.Create(KEY_READ or $0100); This works in the same code for a 32-bit system and a 64-bit system (in my very brief testing - your results may be different).