Installshield新版本安装时卸载旧版本的安装-飞外

安装包升级问题,搞得实在头大,经过反复摸索,最终决定卸载旧的安装,安装新的程序,以达到升级目的。本方案有所局限,对于大型的安装或者配置复杂的安装不适合。本案例用IS2009,InstallScript MSI工程建立测试的。

比如:已安装1.0.0.1版本的程序,现在做了个新的1.0.0.2版本的程序。那么在第一个版本里我们就要开始做以下工作,并在以后版本要记得更改产品ID。

首先,我们需要声明两个方法:

export prototype UninstallOldVersion(); //卸载旧版本
export prototype WriteInstallGuid();//将本安装包的GUID写入注册表

在OnBegin函数里,写判断是否有旧的安装:

声明以下自定义变量

string szNumName,szNumValue;
number nType,nSize;

//旧的安装GUID
RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);
if(RegDBKeyExist(szKey) 0)then
szNumName="Test";
nType=REGDB_STRING;
RegDBGetKeyValueEx(szKey,szNumName,nType,szNumValue,nSize);
oldGuid= szNumValue;//获取旧安装的产品ID
endif;

写一个卸载函数:

function UninstallOldVersion()

string szPath,UninstallString;

string szNumName,szNumValue;

number nType,nSize;

begin

szPath=WINDIR+"Installer\\"+oldGuid;

RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);

UninstallString="\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\InstallShield_"+oldGuid;

nType=REGDB_STRING;

szNumName="UninstallString";

RegDBGetKeyValueEx(UninstallString,szNumName,nType,szNumValue,nSize); //获取卸载脚本

if(RegDBKeyExist(UninstallString) 0) then

if(AskYesNo("Install the software detects an earlier version, in order to ensure the software is installed correctly uninstall that version!",NO)=YES) then

SdShowMsg("Uninstalling the program, please wait ...",TRUE);

Delay(1);

LaunchAppAndWait(szNumValue," /S",LAAW_OPTION_WAIT);

//刷新注册表

LaunchAppAndWait ( "","cmd /c gpupdate /force /wait:0 ",LAAW_OPTION_WAIT|LAAW_OPTION_HIDDEN);

SdShowMsg("", FALSE);

SdShowMsg("Uninstall is complete",TRUE);

Delay(2);

SdShowMsg("", FALSE);

LaunchAppAndWait( WINSYSDIR^"cmd.exe", "/c rd /s/q \""+szPath+"\"", LAAW_OPTION_WAIT | LAAW_OPTION_HIDDEN);

else

abort;

endif;

endif;

end;

我们在OnFirstUIBefore里调用UninstallOldVersion函数,以执行卸载操作;

对于安装包GUID在OnFirstUIAfter里进行写入,在OnFirstUIAfter调用WriteInstallGuid函数,以下为WriteInstallGuid函数脚本:

function WriteInstallGuid()
string svSubStr,productCode;
number nRootKey,nType;
begin
//写注册表
if(OS32=TRUE) then//判断32位还是64位
StrSub(svSubStr,UNINSTALL_STRING,57,38); //获取guid
else
StrSub(svSubStr,UNINSTALL_STRING,63,38);
endif;
productCode=svSubStr;
nRootKey=HKEY_LOCAL_MACHINE;
RegDBSetDefaultRoot(nRootKey);
nType=REGDB_STRING;
RegDBSetKeyValueEx(szKey,"Test",nType,productCode,-1);
end;

至此一个完整的卸载旧版本脚本完毕,感谢Kevin、海洋女神、单车、小董等人的热情帮助,如需转载,请注明出处。竹林逸轩原创。

附上工程所有脚本:

View Code
//===========================================================================// Included header files ----------------------------------------------------#include "ifx.h" //卸载旧的安装#define szKey "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Infomedia_Dog\\" string oldGuid; BOOL OS64,OS32; //获取安装包位置STRING SETUPEXEDIR[MAX_PATH + 1]; string setupDIR; number nBuffer; export prototype UninstallOldVersion(); //卸载旧版本 export prototype WriteInstallGuid();//将本安装包的GUID写入注册表 //---------------------------------------------------------------------------// OnBegin// The OnBegin event is called directly by the framework after the setup// initializes.//---------------------------------------------------------------------------function OnBegin()string szNumName,szNumValue;number nType,nSize; begin  SetTitle(IFX_PRODUCT_NAME + " -Infomedia", 0, BACKGROUNDCAPTION);  //安装包路径 nBuffer=MAX_PATH+1; MsiGetProperty(ISMSI_HANDLE,"SETUPEXEDIR",SETUPEXEDIR,nBuffer); setupDIR= SETUPEXEDIR+"\\DogSetup.exe";  //判断操作系统 if (SYSINFO.bIsWow64) then  OS64=TRUE; else OS32=TRUE; endif; //旧的安装GUID RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);  if(RegDBKeyExist(szKey) 0)then  szNumName="Dog"; nType=REGDB_STRING; RegDBGetKeyValueEx(szKey,szNumName,nType,szNumValue,nSize);  oldGuid= szNumValue;  endif; end; function UninstallOldVersion() string szPath,UninstallString; string szNumName,szNumValue;number nType,nSize; begin szPath=WINDIR+"Installer\\"+oldGuid; RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);UninstallString="\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\InstallShield_"+oldGuid; nType=REGDB_STRING;szNumName="UninstallString";RegDBGetKeyValueEx(UninstallString,szNumName,nType,szNumValue,nSize); //获取卸载脚本 if(RegDBKeyExist(UninstallString) 0) then  if(AskYesNo("Install the software detects an earlier version, in order to ensure the software is installed correctly uninstall that version!",NO)=YES) then  SdShowMsg("Uninstalling the program, please wait ...",TRUE);  Delay(1); LaunchAppAndWait(szNumValue," /S",LAAW_OPTION_WAIT);  //DeleteDir("C:\\Program Files (x86)\\InstallShield Installation Information\\"+oldGuid,ALLCONTENTS); //刷新注册表 LaunchAppAndWait ( "","cmd /c gpupdate /force /wait:0 ",LAAW_OPTION_WAIT|LAAW_OPTION_HIDDEN);  SdShowMsg("", FALSE); SdShowMsg("Uninstall is complete",TRUE); Delay(2); SdShowMsg("", FALSE); LaunchAppAndWait( WINSYSDIR^"cmd.exe", "/c rd /s/q \""+szPath+"\"", LAAW_OPTION_WAIT | LAAW_OPTION_HIDDEN); else abort; endif; endif; end; function OnFirstUIBefore() NUMBER nResult, nSetupType, nvSize, nUser; STRING szTitle, szMsg, szQuestion, svName, svCompany, szFile; STRING szLicenseFile; BOOL bCustom, bIgnore1, bIgnore2;begin  UninstallOldVersion(); if( REMOVEONLY ) then Disable( DIALOGCACHE ); szMsg = SdLoadString( IDS_IFX_ERROR_PRODUCT_NOT_INSTALLED_UNINST ); SdSubstituteProductInfo( szMsg ); MessageBox( szMsg, SEVERE ); abort; endif; nSetupType = TYPICAL; 
nResult = SdAskDestPath(szTitle, szMsg, INSTALLDIR, 0); if (nResult = BACK) goto Dlg_SdAskDestPath;Dlg_ValueAddedServices: nResult = OnFirstUIBeforeValueAddedServices( nResult ); if (nResult = BACK) goto Dlg_SdAskDestPath;Dlg_SdStartCopy: // Added in IS 2009 - Set appropriate StatusEx static text. SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_FIRSTUI ) ); // setup default status Enable(STATUSEX); return 0;end; //---------------------------------------------------------------------------// OnFirstUIAfter// The OnFirstUIAfter event called by the framework after the file transfer// of the setup when the setup is running in first install mode. By default// this event displays UI that informs the end user that the setup has been// completed successfully.//---------------------------------------------------------------------------function OnFirstUIAfter() STRING szTitle, szMsg1, szMsg2, szOpt1, szOpt2; NUMBER bOpt1, bOpt2;begin Disable(STATUSEX); bOpt1 = FALSE; bOpt2 = FALSE; LaunchAppAndWait(TARGETDIR^"reg.bat","",LAAW_OPTION_WAIT|LAAW_OPTION_HIDDEN); LaunchAppAndWait(TARGETDIR^"Raindog_Register.exe","",NOWAIT); WriteInstallGuid();//写注册表 if ( BATCH_INSTALL ) then SdFinishReboot ( szTitle , szMsg1 , SYS_BOOTMACHINE , szMsg2 , 0 ); else // SdFinish ( szTitle , szMsg1 , szMsg2 , szOpt1 , szOpt2 , bOpt1 , bOpt2 ); endif;//---------------------------------------------------------------------------// OnMaintUIBefore// The OnMaintUIBefore event is called by the framework when the setup is// running in maintenance mode. By default this event displays UI that// allows the end user to add or remove features, repair currently// installed features or uninstall the application.//---------------------------------------------------------------------------function OnMaintUIBefore() NUMBER nResult, nType,nBuffer; STRING szTitle, szMsg, svDir, svResult, szCaption; string setupDIR;begin Dlg_Start: if( !REMOVEONLY ) then if(AskYesNo("Already installed, and whether to delete in order to continue?",YES)=NO) then abort; else ComponentRemoveAll(); SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_MAINTUI_REMOVEALL ) ); endif; else ComponentRemoveAll(); SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_MAINTUI_REMOVEALL ) ); endif; // setup default status SetStatusWindow(0, ""); Enable(STATUSEX); StatusUpdate(ON, 100); //---------------------------------------------------------------------------// OnMaintUIAfter// The OnMaintUIAfter event called by the framework after the file transfer// of the setup when the setup is running in maintenance mode. By default// this event displays UI that informs the end user that the maintenance setup// has been completed successfully.//---------------------------------------------------------------------------function OnMaintUIAfter() STRING szTitle, szMsg1, szMsg2, szOpt1, szOpt2; NUMBER bOpt1, bOpt2;begin Disable(STATUSEX); if( REMOVEALLMODE ) then szTitle = SdLoadString(IFX_SDFINISH_REMOVE_TITLE); szMsg1 = SdLoadString(IFX_SDFINISH_REMOVE_MSG1); else szTitle = SdLoadString(IFX_SDFINISH_MAINT_TITLE); szMsg1 = SdLoadString(IFX_SDFINISH_MAINT_MSG1); endif; bOpt1 = FALSE; bOpt2 = FALSE; if ( BATCH_INSTALL ) then SdFinishReboot ( szTitle , szMsg1 , SYS_BOOTMACHINE , szMsg2 , 0 ); else SdFinish ( szTitle , szMsg1 , szMsg2 , szOpt1 , szOpt2 , bOpt1 , bOpt2 ); endif; LaunchAppAndWait(setupDIR,"",NOWAIT); end; function WriteInstallGuid()string svSubStr,productCode; number nRootKey,nType;begin //写注册表 if(OS32=TRUE) then StrSub(svSubStr,UNINSTALL_STRING,57,38); //获取guid else StrSub(svSubStr,UNINSTALL_STRING,63,38); endif; productCode=svSubStr; nRootKey=HKEY_LOCAL_MACHINE; RegDBSetDefaultRoot(nRootKey); nType=REGDB_STRING; RegDBSetKeyValueEx(szKey,"Dog",nType,productCode,-1); end;