安裝包升級問題,搞得實在頭大,經過反覆摸索,最終決定卸載舊的安裝,安裝新的程序,以達到升級目的。本方案有所侷限,對於大型的安裝或者配置複雜的安裝不適合。本案例用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、海洋女神、單車、小董等人的熱情幫助,如需轉載,請註明出處。竹林逸軒原創。
附上工程所有腳本:
//=========================================================================== // 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; Dlg_SdAskDestPath: 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; end; //--------------------------------------------------------------------------- // 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); end; //--------------------------------------------------------------------------- // 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;
轉自:http://www.cnblogs.com/zhulinyixuan/archive/2012/07/11/2585901.html
作者:竹林逸軒