在 Inno Setup 安装程序中,卸载由 InstallShield LE 进行的安装
In Inno Setup installer, uninstall installation made by InstallShield LE
由于 VS 2017 不支持 InstallShield LE,我尝试改用 Inno Setup。
但是如何在使用 Inno Setup 脚本开始安装之前卸载之前由 InstallShield LE 进行的安装。
不同用户(不在同一台计算机上)安装了多个版本的应用程序。
由于版本之间的产品代码不同,Uninstall
注册表项中的 GUID 可能不同,因此很难在注册表的卸载部分找到。
当我编写示例脚本和 the related blog post 时,很明显您应该查询注册表以检测以前安装的软件,
function InitializeSetup(): Boolean;
var
oldVersion: String;
uninstaller: String;
ErrorCode: Integer;
begin
if RegKeyExists(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F768F6BA-F164-4599-BC26-DCCFC2F76855}_is1') then
begin
RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F768F6BA-F164-4599-BC26-DCCFC2F76855}_is1',
'DisplayVersion', oldVersion);
if (CompareVersion(oldVersion, '6.0.0.1004') < 0) then
begin
if MsgBox('Version ' + oldVersion + ' of Code Beautifier Collection is already installed. Continue to use this old version?',
mbConfirmation, MB_YESNO) = IDYES then
begin
Result := False;
end
else
begin
RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F768F6BA-F164-4599-BC26-DCCFC2F76855}_is1',
'UninstallString', uninstaller);
ShellExec('runas', uninstaller, '/SILENT', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
Result := True;
end;
end
else
begin
MsgBox('Version ' + oldVersion + ' of Code Beautifier Collection is already installed. This installer will exit.',
mbInformation, MB_OK);
Result := False;
end;
end
else
begin
Result := True;
end;
end;
您的基于 InstallShield 的安装程序还应将基于 GUID 的子树插入到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\
,因此只需分析其中的内容并采取必要的操作将其卸载。
您可以使用 Inno Setup: How to automatically uninstall previous installed version?
中的代码
虽然答案中的代码用于卸载由 Inno Setup 安装的以前的版本,但它基本上足够通用,可以与任何以前的卸载系统一起使用。
要使其与 InstallShield 一起使用,您需要知道要卸载的版本的产品代码。如果您需要能够删除任何版本,您可以使用升级代码查找实际安装版本的产品代码。为此,您可以使用 WMI 查询:
How to find the UpgradeCode and ProductCode of an installed application in Windows 7.
在 Inno Setup Pascal 脚本中,代码可以是这样的:
const
InstallShieldUpgradeCode = '{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}';
function InitializeSetup(): Boolean;
var
WbemLocator, WbemServices, WbemObjectSet: Variant;
Query: string;
ProductCode: string;
begin
WbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
WbemServices := WbemLocator.ConnectServer('.', 'root\CIMV2');
Query :=
'SELECT ProductCode FROM Win32_Property ' +
'WHERE Property="UpgradeCode" AND Value="' + InstallShieldUpgradeCode + '"';
WbemObjectSet := WbemServices.ExecQuery(Query);
if not VarIsNull(WbemObjectSet) and (WbemObjectSet.Count > 0) then
begin
ProductCode := WbemObjectSet.ItemIndex(0).ProductCode;
{ Start uninstall here }
end;
Result := True;
end;
但请注意,查询可能需要数十秒。
由于 VS 2017 不支持 InstallShield LE,我尝试改用 Inno Setup。
但是如何在使用 Inno Setup 脚本开始安装之前卸载之前由 InstallShield LE 进行的安装。
不同用户(不在同一台计算机上)安装了多个版本的应用程序。
由于版本之间的产品代码不同,Uninstall
注册表项中的 GUID 可能不同,因此很难在注册表的卸载部分找到。
当我编写示例脚本和 the related blog post 时,很明显您应该查询注册表以检测以前安装的软件,
function InitializeSetup(): Boolean;
var
oldVersion: String;
uninstaller: String;
ErrorCode: Integer;
begin
if RegKeyExists(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F768F6BA-F164-4599-BC26-DCCFC2F76855}_is1') then
begin
RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F768F6BA-F164-4599-BC26-DCCFC2F76855}_is1',
'DisplayVersion', oldVersion);
if (CompareVersion(oldVersion, '6.0.0.1004') < 0) then
begin
if MsgBox('Version ' + oldVersion + ' of Code Beautifier Collection is already installed. Continue to use this old version?',
mbConfirmation, MB_YESNO) = IDYES then
begin
Result := False;
end
else
begin
RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F768F6BA-F164-4599-BC26-DCCFC2F76855}_is1',
'UninstallString', uninstaller);
ShellExec('runas', uninstaller, '/SILENT', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
Result := True;
end;
end
else
begin
MsgBox('Version ' + oldVersion + ' of Code Beautifier Collection is already installed. This installer will exit.',
mbInformation, MB_OK);
Result := False;
end;
end
else
begin
Result := True;
end;
end;
您的基于 InstallShield 的安装程序还应将基于 GUID 的子树插入到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\
,因此只需分析其中的内容并采取必要的操作将其卸载。
您可以使用 Inno Setup: How to automatically uninstall previous installed version?
中的代码虽然答案中的代码用于卸载由 Inno Setup 安装的以前的版本,但它基本上足够通用,可以与任何以前的卸载系统一起使用。
要使其与 InstallShield 一起使用,您需要知道要卸载的版本的产品代码。如果您需要能够删除任何版本,您可以使用升级代码查找实际安装版本的产品代码。为此,您可以使用 WMI 查询:
How to find the UpgradeCode and ProductCode of an installed application in Windows 7.
在 Inno Setup Pascal 脚本中,代码可以是这样的:
const
InstallShieldUpgradeCode = '{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}';
function InitializeSetup(): Boolean;
var
WbemLocator, WbemServices, WbemObjectSet: Variant;
Query: string;
ProductCode: string;
begin
WbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
WbemServices := WbemLocator.ConnectServer('.', 'root\CIMV2');
Query :=
'SELECT ProductCode FROM Win32_Property ' +
'WHERE Property="UpgradeCode" AND Value="' + InstallShieldUpgradeCode + '"';
WbemObjectSet := WbemServices.ExecQuery(Query);
if not VarIsNull(WbemObjectSet) and (WbemObjectSet.Count > 0) then
begin
ProductCode := WbemObjectSet.ItemIndex(0).ProductCode;
{ Start uninstall here }
end;
Result := True;
end;
但请注意,查询可能需要数十秒。