微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐