InstallScript项目无法使用Major Upgrade?如何实现自动卸载旧版本
嘿,我来帮你搞定InstallScript项目里自动卸载旧版本再安装新版本的问题——毕竟Major Upgrade确实不支持这类项目,得手动实现类似逻辑。下面是一步步的实操方案:
实现InstallScript项目自动卸载旧版本的完整方案
1. 先检测系统中已安装的旧版本
首先得确认用户机器上有没有装过你的旧版本,InstallScript里可以用MsiGetProductInfo函数直接查询旧版本的ProductCode对应的卸载信息;如果不知道ProductCode,也可以遍历注册表找匹配的产品名称。
举个检测示例:
function FindOldVersion(): BOOL; var szProductCode: STRING; szUninstallString: STRING; nResult: NUMBER; begin // 替换成你的旧版本ProductCode szProductCode = "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"; nResult = MsiGetProductInfo(szProductCode, INSTALLPROPERTY_UNINSTALLSTRING, szUninstallString, 255); if (nResult = ERROR_SUCCESS) then // 找到已安装的旧版本 return TRUE; else return FALSE; endif; end;
提示:如果不确定旧版本ProductCode,可遍历HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall下的子键,通过DisplayName匹配你的产品名称来获取卸载字符串。
2. 执行旧版本的静默卸载
找到卸载命令后,需要启动卸载进程并等待它完成,再继续新版本的安装。这里用LaunchAppAndWait函数来实现:
function UninstallOldVersion(): BOOL; var szProductCode: STRING; szUninstallString: STRING; szCmdLine: STRING; nResult: NUMBER; begin szProductCode = "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"; MsiGetProductInfo(szProductCode, INSTALLPROPERTY_UNINSTALLSTRING, szUninstallString, 255); // 处理卸载命令,加上/qn实现静默卸载(无弹窗) szCmdLine = szUninstallString + " /qn"; // 启动卸载并等待完成 nResult = LaunchAppAndWait("msiexec.exe", szCmdLine, LAAW_OPTION_WAIT); if (nResult = 0) then // 卸载成功 return TRUE; else // 卸载失败,提示用户手动处理 MessageBox("旧版本卸载失败,请手动卸载后再安装新版本。", SEVERE); return FALSE; endif; end;
注意:如果旧版本本身是InstallScript项目(非MSI),卸载命令可能是setup.exe /uninst这类格式,需要对应调整szCmdLine的内容。
3. 在安装流程中嵌入检测与卸载逻辑
把上面的函数放到InstallScript的OnFirstUIBefore或者OnInstalling事件里,确保在安装新版本前执行检测和卸载:
function OnFirstUIBefore(): NUMBER; begin // 先检测旧版本 if (FindOldVersion()) then // 询问用户是否自动卸载 if (MessageBox("检测到已安装旧版本,是否自动卸载后安装新版本?", MB_YESNO) = IDYES) then if (UninstallOldVersion()) then MessageBox("旧版本已成功卸载,即将开始安装新版本。", INFORMATION); else // 卸载失败,终止安装流程 abort; endif; else // 用户拒绝卸载,终止安装 MessageBox("请先卸载旧版本再安装新版本。", SEVERE); abort; endif; endif; // 继续执行后续的安装步骤... end;
4. 版本号判断(可选但推荐)
如果你的产品有多个旧版本,建议加入版本对比逻辑,只卸载低于当前版本的实例:
function IsOldVersionLower(): BOOL; var szOldVersion: STRING; szCurrentVersion: STRING; nCompareResult: NUMBER; begin szCurrentVersion = "2.0.0.0"; // 当前新版本的版本号 MsiGetProductInfo("{旧版本ProductCode}", INSTALLPROPERTY_VERSIONSTRING, szOldVersion, 255); nCompareResult = CompareVersion(szOldVersion, szCurrentVersion); // 旧版本低于当前版本则返回TRUE return (nCompareResult < 0); end;
把这个函数和检测逻辑结合,就能实现只卸载低版本的需求了。
内容的提问来源于stack exchange,提问作者agshah
相关产品推荐
相关产品推荐

