registryinno-setupdllregistration

Inno Setup: remapping of registry hives


Wondering whether there is some way that I wasn't aware of, for Inno Setup to redirect hive constants. More specifically, the ability to invoke, before writing to registry, this function: RegOverridePredefKey.

To provide a little background, this would be, in my case, the preferred way to force a self-registering DLL to register for the current user (that may not have administrator credentials), instead of globally. (In other words, write to HKEY_CURRENT_USER\Software\Classes instead of HKCR.) Haven't found any other Inno Setup construct that would help with this, and I would avoid using 3rd party tools, that would also need updating, if possible.


Solution

  • No, Inno Setup does not support this.

    But it's not that difficult to call it from Pascal Scripting.

    Though note that you cannot use RegOverridePredefKey to redirect HKEY_LOCAL_MACHINE to HKEY_CURRENT_USER. You can only redirect it to a subkey:

    hNewHKey: ... A handle to an open registry key. This handle is returned by the RegCreateKeyEx or RegOpenKeyEx function. It cannot be one of the predefined keys.

    So after registering the DLL, you would have to copy the subkey to the HKEY_CURRENT_USER and delete it (as the documentation for RegOverridePredefKey suggests).

    Basic code for redirecting to a temporary subkey:

    [Files]
    Source: "MyDllServer.dll"; Flags: ignoreversion dontcopy
    
    [Code]
    
    const
      KEY_WRITE = $20006;
      
    function RegOverridePredefKey(Key: Integer; NewKey: Integer): Integer;
      external 'RegOverridePredefKey@advapi32.dll stdcall';
    
    function RegCreateKeyEx(
      Key: Integer; SubKey: string; Reserved: Cardinal; Cls: Cardinal;
      Options: Cardinal; Desired: Cardinal; SecurityAttributes: Cardinal;
      var KeyResult: Integer; var Disposition: Cardinal): Integer;
      external 'RegCreateKeyExW@advapi32.dll stdcall';
    
    function MyDllRegisterServer: Integer;
      external 'DllRegisterServer@files:MyDllServer.dll stdcall delayload';
    
    // ...
    begin
      // Create a subkey to redirect the HKLM to
      RegCreateKeyEx(
        HKEY_CURRENT_USER, 'MyProgTemp', 0, 0, 0, KEY_WRITE, 0, NewKey, Unused);
      // Redirect HKLM to the created subkey
      RegOverridePredefKey(HKEY_LOCAL_MACHINE, NewKey);
      // Call DllRegisterServer of the .dll
      MyDllRegisterServer;
      // Now you can copy the subkey to HKCU
    end;
    

    Add some error handling!

    The code is for Unicode version of Inno Setup.


    For the copying part, you can reuse (and improve) my code from Specify the registry uninstall key location/hive via [Code].