1

I heared that Windows creates a unique key for a PC which is called "MachineID". I found two locations in my registry. Only the location "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography" should be correct. I try to read the value by this function:

 Function GetMaschineID:string; var Reg : TRegistry; //HKEY_CURRENT_USER\Software\Microsoft\MSNMessenger = {dd239a44-fa0d-43ff-a51c-5561d3e39de3} //HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography = a06b0ee0-b639-4f55-9972-146776bcd5e4 begin Reg := TRegistry.Create(KEY_READ); try Reg.Rootkey:=HKEY_LOCAL_MACHINE; //Hauptschlüssel //Reg.RootKey:=HKEY_CURRENT_USER; if Reg.OpenKey('SOFTWARE\Microsoft\Cryptography\',false) then //Unterschlüssel öffnen //if Reg.OpenKey('Software\Microsoft\MSNMessenger\',false) then //Unterschlüssel öffnen begin Result:=Reg.ReadString('MachineGuid'); end; finally Reg.Free; end; end; 

This version results in an empty string; you see as comment the result from the registry. The second version for "hkey_Current_user" brings the expected string result.

What is wrong with my code or are parts of the registry read protected?

2
  • What is wrong with reading from current user? Commented Aug 8, 2015 at 7:26
  • It seems to be there for different usage, maybe an old application (Messenger???), has a different value (see code above) and the source is definitively not the windows installer Commented Aug 8, 2015 at 11:20

2 Answers 2

8

Possible explanation 1

For HKLM you are subject to registry redirection. You have a 32 bit process and are trying to read a key from the 64 bit view of the registry. By default, your 32 bit process is redirected to the 32 bit view, which (implementation detail) lives under Wow6432Node.

Use the KEY_WOW64_64KEY access flag to read from the 64 bit view. As detailed here: How can I read 64-bit registry key from a 32-bit process?

Possible explanation 2

Your call to OpenKey fails for keys under HKLM because you are requesting write access and standard user does not have write access to HKLM. Use OpenKeyReadOnly instead.

Other advice

At the very least you should have debugged this a bit more. Does the call to Reg.OpenKey succeed or fail? You should have debugged enough to know that. Perhaps you did but did not say. If Reg.OpenKey failed then explanation 2 is most likely. Even then, you may subsequently suffer from the other problem.

Note also that your function does not assign to the function result variable, or raise an error, if the call to Reg.OpenKey fails. I would expect that the compiler would have warned you about that.

Sign up to request clarification or add additional context in comments.

6 Comments

I'm sorry I wrote "results in an empty string" this means that Openkey works and the empty string is a result of the "readstring" line. I think your explanation 1 sounds correct. I must understand, needs a moment
An empty string is likely what you'd see if OpenKey failed because you did not assign to Result in that case, and managed types are default initialized.
Anyway, your code example you gave with your answer works very well, Thank you
Are you running elevated? Do you really need to? Because OpenKey should fail for HKLM.
Only if you disabled UAC, are running virtualized, or UAC is enabled and you are elevated, running as admin.
|
-1
procedure TForm1.Button1Click(Sender: TObject); var registry: TRegistry; begin Registry := TRegistry.Create(KEY_READ OR KEY_WOW64_64KEY); try registry.RootKey := HKEY_LOCAL_MACHINE; if (registry.KeyExists('\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL')) and (registry.OpenKeyReadOnly('\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL')) then begin showmessage(registry.ReadString('SQLEXPRESS')); registry.CloseKey; end else showmessage('failed'); finally registry.Free; end; end; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.