views:

91

answers:

1

So far if I had to associate the file extension with my application I used to simply modify the registry. However I haven't been doing it for years, and I'm afraid the things might have changed a bit. I have no idea how to prevent registry access restrictions in Windows 7 / Vista (if there are any for HKEY_CLASSES_ROOT). Thus I'm looking for some delphi library, unit, code snippet or whatever which works reliably under XP, Vista and 7. Is there any which handles "backup" as well? By backup I mean possibility to revert the changes to the previous association...

+4  A: 

I would recommend against using a 3rd-party component for this, for it will only make things more complicated.

We all know how to make file associations by editing the HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE hives, right? In Windows Vista+, editing the former implies no trouble, but if you for some reason want to edit the latter, i.e. if you want to edit the associations for all users on the machine, then your app needs to run with elevated privileges.

To make an application run with elevated privileges, the user can right-click the icon and select "Run as administrator". But that is ugly. One can, however, make an application run as administrator automatically, simply by adding a manifest (an XML file) to the application's resource. Then the UAC prompt will popup automatically upon execution of the *.exe file, no matter how the end user starts the program, and the program will be run as an administrator, and is perfectly able to alter the HKEY_LOCAL_MACHINE hive. The details on how to add this manifest has been explain in several SO questions. It really is easy.

As far as I know, it is not possible for a running application to "upgrade" its privileges at runtime. So if you have a button in your app, running with normal privileges, you cannot do something like this:

procedure Button1.Click(Sender: TObject);
begin
  SomehowGetAdminPrivileges;
  ChangeLocalMachineRegistry;
  SomehowGetBackNormalPrivileges;
end;

That is simply not possible. So if you need to do something that requires admin privileges during runtime, you need to call an external application, as in

procedure Button1.Click(Sender: TObject);
begin
  ShellExecute(Application.Handle, nil, PChar('myapp.exe'), nil, nil, SW_SHOWNORMAL);
end;

myapp.exe needs to have a manifest, so that it will run with raised privileges, and is able to do what you want. But preferably myapp.exe should not have a GUI - when the user clicks the button, the UAC prompt appears, and the the myapp.exe performs the registry change and then terminates.

It would be possible but awkward to accomplish this using a 3rd-party component.

Do you need to change the registry during setup? If you use Inno Setup, the professional and free tool, Inno Setup will include the manifest for you. Hence the UAC prompt will appear when starting setup.exe (compiled with Inno Setup) if the setup requires it, e.g. if the setup will make any changes to HKEY_LOCAL_MACHINE.

Andreas Rejbrand
You do know that `HKEY_CLASSES_ROOT` is a "combination" of subkeys in `HKEY_CURRENT_USER` and `HKEY_LOCAL_MACHINE`, right? See http://en.wikipedia.org/wiki/HKEY_CLASSES_ROOT#HKEY_CLASSES_ROOT_.28HKCR.29
Andreas Rejbrand