delphirunonce

Why can't I make a RunOnce entry in the Windows Registry using TRegistry and Delphi?


I am using the following code to try to make a RunOnce entry:

program RunOnceTest;

{$APPTYPE CONSOLE}

uses
  SysUtils, Registry, Windows;

var
  R: TRegistry;
begin
  try
    WriteLn('Testing RunOnStartup.......');


    R := TRegistry.Create;
    try
      R.RootKey := HKEY_LOCAL_MACHINE;
      R.LazyWrite := False;
      R.OpenKey('Software\Microsoft\Windows\CurrentVersion\RunOnce', True) ;
      R.WriteString('this', 'that') ;
      R.CloseKey;
    finally
      R.free;
    end;

    WriteLn('Test Finished');

    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

I run the app, and it executes.

However, there is no entry at:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce

in my registry. Do I need administrator privileges? What else do I need to do?

ADDED: I should explain better and really ask a question about what I am trying to do. I am trying to get my app to run automatically at startup. Lot's of applications do this without appearing to require admin privileges. What is the normal way to do this?


Solution

  • First of all you need to have admin rights to write there. Mostly it's just installers that write to this key and they generally run elevated. Add this to your application manifest if that's the way you want to go:

    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
      <security>
        <requestedPrivileges>
          <requestedExecutionLevel
            level="requireAdministrator"
            uiAccess="false"/>
        </requestedPrivileges>
      </security>
    </trustInfo>
    

    If this write to HKLM is being made from an application that doesn't otherwise need elevation then please consider separating out the write to HKLM into a separate process so that only that registry key write needs elevation. This is best practise with UAC.

    The other thing that might bite you is that your Delphi app will be 32 bit and so subject to registry redirection. Accesses of HKLM\Software will get redirected to HKLM\Software\Wow6432Node.

    On a 64 bit system I think you should endeavour to write to HKLM\Software and so you'll need to disable redirection. Do this by including KEY_WOW64_64KEY in the Access property of your TRegistry instance.

    Windows will merge both views of the registry when it processes Run and RunOnce keys but your application will leave clearer trails if you write to the 64 bit area of the registry for this particular key.