inno-setup – 通过[Code]指定注册表卸载密钥位置/配置单元

Inno Setup默认查看PrivilegesRequired设置变量,如果设置为admin或poweruser,则安装程序会将卸载注册表项安装到HKLM.如果将其设置为最低,则会将注册表项安装到HKCU.

我要求为用户提供“仅我”或“每个人”的安装选项,并通过用这两个选项的无线电选择替换目录选择页面来完成.我现在需要做的是根据此设置修改注册表安装位置.如果我将应用程序安装到本地用户应用程序数据中,则在HKLM级别注册卸载数据是没有意义的,因为其他用户将在程序列表中看到它并仍然无法卸载或使用它.

编辑:在查看了文档和Install.pas的源代码后,我找到了CreateUninstallRegKey安装指令,它将禁止Inno完全安装注册表项,之后我可以添加自己的注册表项,但这真的是唯一的方法?

编辑#2(标记为重复):我已经看过这个Conditional Elevation问题(并实际实现了它),它与我的不一样.当前提升状态不会改变Inno Setup实际保存卸载注册表信息的位置(在HKCU或HKLM中).如果查看Inno source code (Install.pas #507),您会看到PrivilegesRequired指令是存储注册表的主要因素.如果将此设置为最低,则无论安装程序是否提升都无关紧要 – 它将安装注册表项到HKCU,当所需的行为是根据用户安装首选项选择一个或另一个时,而不是当前的提升状态.所以这就是说,我正在寻找一种解决方案来根据代码变量更改注册表根目录,无论当前的PrivilegesRequired或Elevation设置如何.

解决方法

正如您自己发现的那样,逻辑是硬编码的.你无法控制它.

您可以获得的最接近的是使用未记录的(已弃用)PrivilegesRequired = none.

使用此值(并在Windows中使用installer-autodetection帮助):

>使用未授权帐户启动安装程序时,它会在不提示您提升的情况下启动.如果您决定在安装过程中需要升高,则可以使用restart the installer elevated.
>当您使用特权帐户启动安装程序时,它始终会提示您提升,如果拒绝,则不会启动.因此安装程序始终运行升级.同样,如果您决定继续进行升级,则必须重新启动安装程序.见How to Start a Process UnelevatedRun un-elevated command from an elevated prompt?.

这不完全是你想要的,但我认为你不能更接近.

您当然可以通过以下代码在HKCU和HKLM之间复制(移动)注册表项:

function MoveHKCUUninstallKeyToHKLM: Boolean;
var
  UninstallKey: string;
  AppId: string;
  I: Integer;
  ValueNames: TArrayOfString;
  ValueName: string;
  ValueStr: string;
  ValueDWord: Cardinal;
begin
  if '{#emit SetupSetting("AppId")}' <> '' then
  begin
    AppId := '{#emit SetupSetting("AppId")}';
  end
    else
  begin
    AppId := '{#emit SetupSetting("AppName")}';
  end;

  Result := False;
  if AppId = '' then
  begin
    Log('Cannot identify AppId');
  end
    else
  begin
    UninstallKey :=
      'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + AppId + '_is1';
    Log(Format(
      'AppId identified as "%s",using uninstall key "%s"',[AppId,UninstallKey]));
    if not RegKeyExists(HKEY_CURRENT_USER,UninstallKey) then
    begin
      Log('HKCU uninstall key not found');
    end
      else
    if RegKeyExists(HKEY_LOCAL_MACHINE,UninstallKey) then
    begin
      Log('HKLM uninstall key exists already');
    end
      else
    begin
      Log('HKCU uninstall key found and HKLM key not exists yet');

      if not RegGetValueNames(HKEY_CURRENT_USER,UninstallKey,ValueNames) then
      begin
        Log('Cannot list uninstall key values');
      end
        else
      begin
        I := 0;
        Result := True;
        while (I < GetArrayLength(ValueNames)) and Result do
        begin
          ValueName := ValueNames[I];
          if RegQueryStringValue(HKEY_CURRENT_USER,ValueName,ValueStr) then
          begin
            if not RegWriteStringValue(
                     HKEY_LOCAL_MACHINE,ValueStr) then
            begin
              Log(Format('Error moving "%s" string value',[ValueName]));
              Result := False;
            end
              else
            begin
              Log(Format('Moved "%s" string value',[ValueName]));
            end;
          end
            else
          if RegQueryDWordValue(
               HKEY_CURRENT_USER,ValueDWord) then
          begin
            if not RegWriteDWordValue(
                     HKEY_LOCAL_MACHINE,ValueDWord) then
            begin
              Log(Format('Error moving "%s" dword value',[ValueName]));
              Result := False;
            end
              else
            begin
              Log(Format('Moved "%s" dword value',[ValueName]));
            end;
          end
            else
          begin
            { All uninstall values written by Inno Setup are either string or dword }
            Log(Format('Value "%s" is neither string nor dword',[ValueName]));
            Result := False;
          end;
          Inc(I);
        end;

        if Result then
        begin
          if not RegDeleteKeyIncludingSubkeys(HKEY_CURRENT_USER,UninstallKey) then
          begin
            Log('Error removing HKCU uninstall key');
            Result := False;
          end
            else
          begin
            Log('Removed HKCU uninstall key');
          end;
        end;

        if not Result then
        begin
          if not RegDeleteKeyIncludingSubkeys(HKEY_CURRENT_USER,UninstallKey) then
          begin
            Log('Failed to move uninstall key to HKLM,' +
                'and also failed to rollback the changes');
          end
            else
          begin
            Log('Failed to move uninstall key to HKLM,rolled back the changes');
          end;
        end;
      end;
    end;
  end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssPostInstall then
  begin
    Log('Post install');
    MoveHKCUUninstallKeyToHKLM;
  end;
end;

相关文章

 从网上看到《Delphi API HOOK完全说明》这篇文章,基本上都...
  从网上看到《Delphi API HOOK完全说明》这篇文章,基本上...
ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c+&#x...
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和ED...
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的...