zoukankan      html  css  js  c++  java
  • 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;
  • 相关阅读:
    MySQL的用户名不记得了怎么办?
    辨析:机器字长、存储字长、指令字长和操作系统位数
    基于Flask框架搭建视频网站的学习日志(六)之数据库
    基于Flask框架搭建视频网站的学习日志(三)之原始web表单
    基于Flask框架搭建视频网站的学习日志(二)
    Docker 容器的网络连接 & 容器互联
    Docker DockerFile文件指令 & 构建
    linux :没有找到 ifconfig netstat
    ubuntu : 无法安全地用该源进行更新,所以默认禁用该源。
    Docker 守护进程的配置和操作 & 远程访问
  • 原文地址:https://www.cnblogs.com/zhulinyixuan/p/2585901.html
Copyright © 2011-2022 走看看