我正在IS 2015 Professional中进行新的基本MSI安装,它是以前安装了installscript MSI(我认为是在2012年制作)的产品的重大升级。
版本,产品和软件包代码不同,它们共享升级代码。
旧版安装提供了为所有用户或仅当前用户安装的选项,新安装目前已设置为“所有用户'仅
在虚拟机中进行测试时(已为所有用户安装了旧版本'),旧安装将卸载,新版本将成功安装,但旧版本中的旧版本仍会保留,版。新版本的新条目当然也存在。
令人沮丧的部分是我确信我有一点工作(最初我有问题,因为我没有设置升级路径),但我不知道我可能改变了什么导致此错误。
我有什么想法可以解决这个问题或者下一步要去哪看?
答案 0 :(得分:0)
这是InstallShield 2012中已知(但未被贬低)的错误。
如果您对使用IS 2012编写的MSI项目进行主要或次要升级,则会将旧的InstallShield_ {}密钥保留在HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
下。
这使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
更智能的比较。
答案 1 :(得分:0)
我最终得到2个CA的32位和1位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在密钥的路径中)。