Inno Setup:重新映射注册表配置单元

Inno Setup: remapping of registry hives

想知道是否有一些我不知道的方法,让 Inno Setup 重定向配置单元常量。更具体地说,在写入注册表之前调用此函数的能力:RegOverridePredefKey.

为了提供一点背景知识,在我的例子中,这是强制自注册 DLL 为当前用户(可能没有管理员凭据)而不是全局注册的首选方法。 (换句话说,写入 HKEY_CURRENT_USER\Software\Classes 而不是 HKCR。)还没有找到任何其他 Inno Setup 结构可以帮助解决这个问题,我会避免使用 3rd party tools,这也会如果可能,需要更新。

不,Inno Setup 不支持这个。

但是从 Pascal 脚本中调用它并不难。

但请注意,您不能使用 RegOverridePredefKeyHKEY_LOCAL_MACHINE 重定向到 HKEY_CURRENT_USER。您只能将其重定向到子项:

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.

因此在注册 DLL 之后,您必须将子项复制到 HKEY_CURRENT_USER 并将其删除(如 RegOverridePredefKey 的文档所建议的那样)。

重定向到临时子项的基本代码:

[Files]
Source: "MyDllServer.dll"; Flags: ignoreversion dontcopy

[Code]

const
  KEY_WRITE = 006;
  
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;

添加一些错误处理!

该代码适用于 Inno Setup 的 Unicode 版本。


对于复制部分,您可以重用(并改进)我来自 的代码。