InstallShield:新的基本MSI主要升级从旧的InstallScript MSI留下旧的ARP条目



我正在IS 2015 Professional中安装一个新的Basic MSI,这是对以前安装了installscript MSI(我认为是2012年制造的)的产品的重大升级。

版本、产品和程序包代码不同,它们共享一个升级代码。

旧安装提供了为所有用户或仅为当前用户安装的选项,新安装当前设置为仅为"所有用户"。

在virtualbox中测试时(已为"所有用户"安装了旧版本),旧安装将卸载,新版本将成功安装,但旧版本的"添加/删除程序"中仍有一个损坏的条目。当然,新版本的新条目也会出现。

令人沮丧的是,我确信我曾经有过这种情况(最初我有问题,因为我没有设置升级路径),但我不知道我可能更改了什么来导致这个错误。

你知道我该怎么解决这个问题,或者下一步该去哪里看吗?

这是InstallShield 2012中的一个已知(但未提示)错误。
如果您对使用is 2012编写的MSI项目进行主要或次要升级,则会在HKLMSOFTWAREMicrosoftWindowsCurrentVersionUninstall下保留旧的InstallShield_{}密钥
这将使Windows在"添加/删除程序"中显示旧条目。

我不知道解决这个问题的好方法,我所做的是编写一个InstallScript函数,在每次升级结束时调用它;请参见下文。参数是ARP中显示的产品名称。该功能删除所有具有此显示名称的键,当然,除了刚刚安装的键!

function FixMajorUpgradeBug(szDisplayName)
STRING szFunctionName,szBaseKey,svString,svValue;
LIST listResults;
NUMBER nResult;
begin
szBaseKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
// go over the key, and remove all InstallShield_{} keys which have the given display name, except for the version installed by this very setup
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
listResults = ListCreate(STRINGLIST);
nResult = RegDBQueryKey(szBaseKey,REGDB_KEYS,listResults);
if nResult = 0 then
nResult = ListGetFirstString (listResults, svString); 
while (nResult != END_OF_LIST) 
if (svString % "InstallShield_{") then
if !(svString % PRODUCT_GUID) then
// delete only keys with the specified product name!
svValue = "";
GU_RegistryGetValue(szBaseKey + "\" + svString,"DisplayName",svValue);
if (svValue = szDisplayName) then
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
RegDBDeleteKey(szBaseKey + "\" + svString);
endif;
endif;
endif;
nResult = ListGetNextString (listResults, svString); 
endwhile; 
endif;
ListDestroy(listResults);
end;

注意-如果您的产品在每次升级后都会更改显示名称(例如,名称中包含版本号),则您需要进行比svValue = szDisplayName更明智的比较。

我最终得到了2个CA,一个用于32位,一个为64位。64位:"[SystemFolder]cmd.exe"/C"echo y|reg delete HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\InstallShield_[ISACTIONPROP1]">

作为具有执行条件的提交执行CA:VersionNT64 AND IS_MAJOR_UPGRADE

其中"ISACTIONPROP1"是在升级路径中定义的(作为"检测属性"),用于保存以前的产品代码。

CA在Install Exec中执行(在"WriteRegistryValues"和Admin Exec序列之后(在"ScheduleReboot"之后)。

32位CA几乎完全相同,只是条件为"NOT VersionNT64",注册表路径不同(基本上在键的路径中没有Wow6432)。

最新更新