-1

I am trying to add values to Internet Explorer's Registry key from an addon. My understanding is if OpenKey() doesn't find the Registry key, then it creates the key because of the true parameter I am using. But it's not being created, and the function returns false. Any idea what I'm doing wrong?

procedure DoInitialization;
var
  ...
  reg1: TRegistry;
begin
  reg1 := tRegistry.Create(KEY_ALL_ACCESS);
  try 
    if reg1.OpenKey('HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\Low Rights\ElevationPolicy\{B93642D4-0A6D-11DF-AD36-FF4756D89593}', true) then begin    
      reg1.WriteString('AppPath', ClientDir);
      reg1.WriteInteger('Policy', $00000003);
      reg1.WriteString('AppName', 'xxxxxxxx.exe');
    end else
      ShowMessage('False');
  finally
    reg1.CloseKey;
  end;
  ...
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Brian
  • 307
  • 2
  • 15
  • http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Win.Registry.TRegistry.OpenKey Read the documentation, it seems clear to me – David Heffernan Mar 09 '18 at 23:14
  • Sorry that was a mistake in the example. I originally tried it with True and it wasn't writing to the registry. – Brian Mar 09 '18 at 23:17
  • Please [edit] your question title to be something other than a regurgitation of tags. *Delphi Internet Explorer Delphi* is all useless noise, especially since your question actually has nothing to do with IE or a browser add-on. Your title should convey some meaning about your question that will be of use to a future reader seeing it in a list of search results to differentiate it from others. Your question is about TRegistry. Also see the documentation, especially `TRegistry.RootKey`. – Ken White Mar 09 '18 at 23:25
  • Read Registry.LastError after the failure to see why it failed. Also, you leak Registry. – David Heffernan Mar 09 '18 at 23:26

2 Answers2

1

The root key is to be set in the RootKey property, not the key.

reg1.RootKey := HKEY_CURRENT_USER;
if reg1.OpenKey('Software\...', True) then begin
  ....

In fact, HKEY_CURRENT_USER is the default so strictly speaking you don't need to set it. But it is, in my opinion, helpful to be explicit.

If that fails then likely you have got a mistake in the registry key string, or perhaps the user does not have sufficient rights. Use the LastError property of reg1 to find out why the call failed.

Note that you leak reg1. You need to destroy the object in the finally block.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • the "..." means there was more code. I freed reg1 but it was cut off from the example. – Brian Mar 09 '18 at 23:43
  • The call to Free needs to be in the finally block in the question and it's pointless calling CloseKey, destroying the object is enough. – David Heffernan Mar 09 '18 at 23:48
  • Again there is more code. I added the "..." because this is where it's failing, not later. – Brian Mar 09 '18 at 23:49
  • I tried reg1.RootKey := HKEY_CURRENT_USER; and I'm still getting false returned. – Brian Mar 09 '18 at 23:50
  • sounds like you are trying to argue with me. Please I'm trying to figure out why reg1.openkey is not working. I am not asking for help on what to do after this. – Brian Mar 09 '18 at 23:54
  • FOCUS PLEASE! I am asking for help with openKey not the leaks. For the error code I tried reg1.LastError and the compiler didn't like that.Tried SysErrorMessage(GetLastError) and got "operation completed successfully" – Brian Mar 10 '18 at 00:03
  • I know. Which is why I added the comment about your leaks as an afterthought. I was just correcting you when you kicked back. I guess you have an old version of Delphi without LastError. You didn't say which version you use. Older versions don't let you obtain error codes at all. GetLastError won't help because the error code doesn't travel that way. It's the return value from the call to RegCreateKeyEx. Checking that under the debugger would help. – David Heffernan Mar 10 '18 at 00:07
  • I am using Delphi 7. I'm modifying old code that the company plans to upgrade before the end of the year. – Brian Mar 10 '18 at 00:11
  • Enable Debug DCUs, step into the OpenKey call, and check the return value of the call to RegCreateKeyEx. That's the error code. Learning how to debug these sort of problems will be really useful for you. – David Heffernan Mar 10 '18 at 00:13
  • @Brian: `TRegistry` does not have a `LastError` property in Delphi 7, and the Registry API does not use `GetLastError()` to report errors. The only way you will be able to get the error code is to either 1) step into `OpenKey()` with the debugger, or 2) call the Win32 API `RegCreateKeyEx()` function directly. – Remy Lebeau Mar 10 '18 at 04:41
1

DON'T use KEY_ALL_ACCESS, that requires admin rights to use. In this situation, you are just writing values to the key, so all you need to use is KEY_SET_VALUE instead. Don't request more rights than you actually need.

Also, you need to use the RootKey property to specify HKEY_CURRENT_USER, do not include it in the key path string.

And, you are leaking the TRegistry object.

Try this instead:

procedure DoInitialization;
var
  ...
  reg1: TRegistry;
begin
  reg1 := TRegistry.Create(KEY_SET_VALUE);
  try 
    reg1.RootKey := HKEY_CURRENT_USER;
    if reg1.OpenKey('\SOFTWARE\Microsoft\Internet Explorer\Low Rights\ElevationPolicy\{B93642D4-0A6D-11DF-AD36-FF4756D89593}', true) then
    begin    
      try
        reg1.WriteString('AppPath', ClientDir);
        reg1.WriteInteger('Policy', $00000003);
        reg1.WriteString('AppName', 'xxxxxxxx.exe');
      finally
        reg1.CloseKey;
      end;
    end else
      ShowMessage('False');
  finally
    reg1.Free;
  end;
  ...
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Why would you need admin right in HKCU? I agree that KEY_ALL_ACCESS is over the top but I didn't mention it because I didn't think it mattered in HKCU. – David Heffernan Mar 10 '18 at 06:34
  • @DavidHeffernan `KEY_ALL_ACCESS` includes rights to alter security access and ownership, so requires an admin to use it – Remy Lebeau Mar 10 '18 at 09:15
  • Don't you also need KEY_CREATE_SUB_KEY in case the key needs to be created. – David Heffernan Mar 10 '18 at 10:10
  • @DavidHeffernan not in this case, no, since the `hKey` passed to `RegCreateKeyEx()` is the `HKEY_CURRENT_USER` key itself. `KEY_CREATE_SUB_KEY` would be needed if you opened the `ElevationPolicy` key first, then created the `{B93642D4-0A6D-11DF-AD36-FF4756D89593}` key relative to it – Remy Lebeau Mar 10 '18 at 16:44
  • In my tests `HKCU` and `KEY_ALL_ACCESS` (the [default values](http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Win.Registry.TRegistry.Create) for Delphi `TRegistry`) work fine for reading/writing/creating/deleting keys and values with non-admin and not-elevated admin users. – JRL Mar 10 '18 at 18:53
  • @JRL it is still not a good idea to request more rights than you actually need for any given operation – Remy Lebeau Mar 10 '18 at 19:49
  • Thank you for your advice. It did not work again, but when I change the window user to one with more permissions it did work, so my main problem appears to be a rights issue. – Brian Mar 13 '18 at 16:03