Firstly, I'm going to take it as read that your program is running elevated. If that's not happening then there's no need to look at any code. You did not say otherwise, so let us proceed under the assumption that you are succeeding to elevate.
You are suffering from the registry redirector. Your 32 bit process is running on a 64 bit machine. And so HKLM\Software is redirected to the 32 bit view, stored at HKLM\Software\Wow6432Node.
You can, if you need, use the KEY_WOW64_64KEY flag to access the 64 bit view. Combine this with the flags in the registry object's Access property.
However, the system reads keys from both 32 and 64 bit views of the registry when enumerating the startup programs so you do not need to do this. For the sake of simplicity and predictability I would leave your 32 bit program writing to the 32 bit view.
Your call to CreateKey should be removed. The system creates that key and you can safely assume it exists. And you should not use TRegIniFile. Use TRegistry instead.
Your code should look like this:
procedure AddEntryToRegistry;
var
Reg: TRegistry;
begin
Reg := TRegistry.Create(KEY_ALL_ACCESS);
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', False) then
Reg.WriteString('MyApp', 'C:\MyApp.exe');
finally
Reg.Free;
end;
end;
Should you feel that you need to write to the 64 bit view then it is done like this:
procedure AddEntryToRegistry;
var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
Reg.Access := KEY_ALL_ACCESS or KEY_WOW64_64KEY;
if Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', False) then
Reg.WriteString('MyApp', 'C:\MyApp.exe');
finally
Reg.Free;
end;
end;
Judging by your comments, it looks like you might be failing to elevate. The lack of a UAC dialog when your program starts is the tell-tale sign that this is happening. Once your program starts without a UAC dialog, there's no point continuing. You will not write to HKLM without elevation.
Regarding your manifest, you can link only one. So if you want to specify a manifest other than the Enable runtime themes manifest that the IDE can provide, you need to do it all yourself.
In the project options specify that you want to use a custom manifest. That's under Project | Options | Application | Runtime themes. Set the drop down to Use custom manifest. And then supply the file name of your manifest. You'll want to add in the comctl32 v6 part to make sure that you get runtime themes. But don't worry about that now. Just concentrate on getting elevation sorted, and the registry code working.
You are also silently ignoring any errors which does make things a little harder to debug. If it so happens that you are not elevating, then running the code is rather pointless. You know it must fail. But you could at least make it easier to diagnose the problem by throwing an error if OpenKey fails.
procedure AddEntryToRegistry;
var
Reg: TRegistry;
begin
Reg := TRegistry.Create(KEY_ALL_ACCESS);
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if not Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', False) then
raise EMyExceptionClass.Create('Could not open registry key');
Reg.WriteString('MyApp', 'C:\MyApp.exe');
finally
Reg.Free;
end;
end;
One final point to make is that writing to this registry key is an admin task. You should require elevation once only, not every time your application starts. If you are planning to require elevation for your application just for this purpose, then you must re-design. This admin task should be performed outside your main application. The most natural place is inside your install program which users will accept requiring elevation.