问题描述
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;