1. 现象:
软件A和软件B在注册表同一个节点下有各自的子节点,比如在
HKEY_LOCAL_MACHINE\Software\MyCompany\COMMON下有SoftwareA和SoftwareB两个子项,各自又分别有自己的键值。
在卸载时发现先安装的软件被卸载后,COMMON这一层的节点也会被删除,导致另一个软件的注册项也被删除。
2.原因
安装脚本中用如下代码添加注册表项:
RegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE ); RegDBCreateKeyEx ("Software\\MyCompany\\COMMON\\SoftwareA" ,""); RegDBSetKeyValueEx ("Software\\MyCompany\\COMMON\\SoftwareA", "Value1" , REGDB_STRING , "xxx" , -1); RegDBSetKeyValueEx ("Software\\MyCompany\\COMMON\\SoftwareA", "Value2" , REGDB_STRING , "xxx" , -1);
上述第二句在创建节点时,如果发现上一层不存在,则会逐层依次添加,而添加的节点都会被InstallShield记录下来,以便在卸载时删除这些节点。第一个软件安装时创建了COMMON节点,其他软件安装时无需再创建,卸载时也就不会删除,而第一个安装的软件在卸载时会删除COMMON节点,导致COMMON节点下的子节点被一并删除。
3. 解决方法
在RegDBCreateKeyEx("Software\\MyCompany\\COMMON\\SoftwareA" ,"");语句前加入如下代码:
if(RegDBKeyExist("Software\\MyCompany\\COMMON") < 0) then Disable(LOGGING); RegDBCreateKeyEx ("Software\\MyCompany\\COMMON" ,""); Enable(LOGGING); endif;
Disable(LOGGING);表示禁用InstallShield的记录功能,此后的操作不会被记录,因此在卸载时也不会恢复。Enable则重新恢复记录功能。
上述代码的一个隐患是COMMON节点永远不会被删除,不过可以在卸载脚本中添加代码进行判断,当COMMON下没有子节点时将其删除。