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;    


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;
原文地址:https://www.cnblogs.com/zhulinyixuan/p/2585901.html