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

时间:2016-05-27 22:18:50

标签: windows-installer install upgrade installshield uninstall

我正在IS 2015 Professional中进行新的基本MSI安装,它是以前安装了installscript MSI(我认为是在2012年制作)的产品的重大升级。

版本,产品和软件包代码不同,它们共享升级代码。

旧版安装提供了为所有用户或仅当前用户安装的选项,新安装目前已设置为“所有用户'仅

在虚拟机中进行测试时(已为所有用户安装了旧版本'),旧安装将卸载,新版本将成功安装,但旧版本中的旧版本仍会保留,版。新版本的新条目当然也存在。

令人沮丧的部分是我确信我有一点工作(最初我有问题,因为我没有设置升级路径),但我不知道我可能改变了什么导致此错误。

我有什么想法可以解决这个问题或者下一步要去哪看?

2 个答案:

答案 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在密钥的路径中)。