Inno Setup检测是否有不同版本应用已经安装并提供卸载选项

问题描述

Inno Setup打包应用后,怎么判断是否有相同版本或者新版本安装怎么提示卸载旧版本,安装新版本。

解决方案:

首先定义安装目录,并将版本号和安装路径写入注册表,以便下次安装时检查

[Dirs]
Name: "{app}"; Permissions: users-full
; 在Registry标签中写入
[Registry]
Root: HKCU; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; ValueType: string; ValueName: "Version"; ValueData: "{#MyAppVersion}"; Flags: uninsdeletekey
Root: HKCU; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}"; Flags: uninsdeletekey

在Inno Setup脚本中,[Dirs]部分用于定义安装目录及其权限

  • Name: “{app}”; 指定了安装目录的名称。“{app}” 是Inno Setup中的一个特殊目录变量,它代表应用程序的安装目录。在安装过程中,"{app}"会被替换为实际的安装路径,通常是由用户在安装过程中选择的路径,或者在安装脚本中预定义的路径。
  • Permissions: users-full 设置了目录的权限。这里指定的是“users-full”,意味着安装目录将被设置为允许所有用户对该目录拥有完全控制权限。

在Inno Setup脚本中,[Registry]部分用于定义安装过程中需要修改的Windows注册表项

  • Root: HKCU 指定了注册表的根键是HKEY_CURRENT_USER,即当前用户的注册表分支。
  • Subkey: 表示在当前用户的注册表的Software下,创建类似AppName\AppVersion的文件夹
  • ValueType:写入注册表变量的类型
  • ValueName:写入注册表变量的名称
  • ValueData: 写入注册表变量的值
  • Flags: uninsdeletekey: 表示在卸载应用程序时,应该删除这个特定的注册表项。

其次自定义一个Pascal函数去判断是否有相同版本应用已经被安装

[Code]
// 首先定义 CloseApplication 过程
procedure CloseApplication;
var
  ResultCode: Integer;
begin
  // 尝试结束可能运行的程序进程
  Exec('taskkill.exe', '/F /IM "{#MyAppExeName}"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  Sleep(1000); // 等待进程完全结束
end;

function IsAppInstalled: Boolean;
var
  RegVersion: string;
  RegKey: string;
  Names: TArrayOfString;
  I: Integer;
  InstallPath: string;
  UninstallExe: string;
  ResultCode: Integer;
begin
  Result := False;
  
  if RegGetSubkeyNames(HKCU, 'Software\{#MyAppName}', Names) then
  begin
    for I := 0 to GetArrayLength(Names) - 1 do
    begin
      RegKey := 'Software\{#MyAppName}\' + Names[I];
      if RegQueryStringValue(HKCU, RegKey, 'Version', RegVersion) then
      begin
        if RegVersion = '{#MyAppVersion}' then
        begin
          MsgBox('已经安装了相同版本的 ICD(版本:' + RegVersion + ')。', mbInformation, MB_OK);
          Result := True;
          Exit;
        end
        else
        begin
          if MsgBox('检测到已安装其他版本的 ICD(版本:' + RegVersion + ')。' + #13#10 + 
                    '是否卸载旧版本并继续安装新版本({#MyAppVersion})?', 
                    mbConfirmation, MB_YESNO) = IDYES then
          begin
            // 获取旧版本的安装路径
            if RegQueryStringValue(HKCU, RegKey, 'InstallPath', InstallPath) then
            begin
              UninstallExe := InstallPath + '\unins000.exe';
              
              // 确保进程已结束
              CloseApplication;
              
              // 执行卸载程序
              if FileExists(UninstallExe) then
              begin
                if Exec(UninstallExe, '/SILENT /NORESTART', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
                begin
                  Sleep(3000); // 等待卸载完成
                  Result := False;  // 卸载成功,继续安装
                  Exit;
                end
                else
                begin
                  MsgBox('卸载旧版本失败,请手动卸载后重试。错误代码:' + IntToStr(ResultCode), mbError, MB_OK);
                  Result := True;
                  Exit;
                end;
              end
              else
              begin
                MsgBox('找不到卸载程序:' + UninstallExe, mbError, MB_OK);
                Result := True;
                Exit;
              end;
            end;
          end
          else
          begin
            Result := True; // 用户选择不卸载,退出安装
            Exit;
          end;
        end;
      end;
    end;
  end;
end;

function InitializeSetup: Boolean;
begin
  if IsAppInstalled then
    Result := False
  else
    Result := True;
end;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值