杉宫竹苑工作室

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2960|回复: 0

InstallShield 实现二次安装时的覆盖安装

[复制链接]
发表于 2017-3-1 18:33:02 | 显示全部楼层 |阅读模式

正式会员享受无限制浏览网站功能和高速网盘下载,赶快加入本站吧!

您需要 登录 才可以下载或查看,没有账号?立即注册

x
实现点
覆盖安装(note : InstallShield本来就提供, 需要注意的是 : InstallShield工程的新版本要增加版本号,不能是原来的版本号. 打包用的PE文件版本号需要比已经安装的PE文件版本号高, 而且必须要是改前三位版本号,不能改第四位版本号. 否则不能覆盖安装. e.g. 旧PE版本号 1.0.1.0, 新版本号码不能为1.0.1.9, 可以为 9.0.1.0, 1.9.1.0, 1.0.9.0)
对已经安装的旧版本进行检测, 通过查InstallShield自带帮助, 翻了好久,发现可以用 MAINTENANCE 来判断
当用户选择安装时,直接安装. 我采用了跳过 OnMaintUIBefore() 中 SdWelcomeMaint, 直接对 nType 赋值成 REPAIR, 来实现
当用户选择不安装时, 在 OnFirstUIBefore() 和 OnMaintUIBefore() 处 abort 实现安装程序退出.
  1. #include "ifx.h"

  2. prototype IsProductWasInstalled();
  3. prototype GetUnInstallExePathName(BYREF STRING);
  4. prototype RunUnInstallExe();

  5. BOOL g_bSetupNow; ///< 如果旧版程序已经安装, 记录用户选择(是否覆盖安装)

  6. function OnBegin()
  7. begin
  8.     // TODO: Perform custom initialization steps, check requirements, etc.
  9.     g_bSetupNow = TRUE;
  10.     if IsProductWasInstalled() then
  11.         if (AskYesNo("已经发现本软件已经被安装!\r\n" + "是否继续安装?", YES) = NO) then
  12.             g_bSetupNow = FALSE; ///< 用户选择不安装
  13.             // RunUnInstallExe();
  14.         endif;
  15.     endif;
  16. end;                              

  17. function IsProductWasInstalled()
  18.     BOOL bRc;
  19. begin
  20.     if (MAINTENANCE != 0) then
  21.         // 产品已经被安装过
  22.         bRc = TRUE;
  23.     else
  24.         // 产品首次被安装(还没有被安装,本次安装是首次)
  25.         bRc = FALSE;
  26.     endif;                    

  27.     return bRc;
  28. end;      

  29. function GetUnInstallExePathName(strPathName)
  30.     BOOL bRc;
  31. begin                              
  32.     if (RegDBGetItem(REGDB_UNINSTALL_MODIFYPATH, strPathName) < 0) then
  33.         bRc = FALSE;
  34.     else  
  35.         bRc = TRUE;
  36.     endif;

  37.     return bRc;
  38. end;        

  39. function RunUnInstallExe()
  40.     STRING strUnInstallPathName;
  41. begin
  42. /**
  43.         if (GetUnInstallExePathName(strUnInstallPathName)) then
  44.             LaunchAppAndWait(strUnInstallPathName, "", WAIT);
  45.         endif;
  46.         */
  47.         ComponentRemoveAll();
  48. end;
  49. //---------------------------------------------------------------------------                                                                        
  50. // OnFirstUIBefore
  51. //
  52. // First Install UI Sequence - Before Move Data
  53. //
  54. // The OnFirstUIBefore event is called by OnShowUI when the setup is
  55. // running in first install mode. By default this event displays UI allowing
  56. // the end user to specify installation parameters.
  57. //
  58. // Note: This event will not be called automatically in a
  59. // program...endprogram style setup.
  60. //---------------------------------------------------------------------------
  61. function OnFirstUIBefore()
  62.     number  nResult, nLevel, nSize, nSetupType;
  63.     string  szTitle, szMsg, szOpt1, szOpt2, szLicenseFile;
  64.     string  szName, szCompany, szTargetPath, szDir, szFeatures;
  65.     BOOL    bLicenseAccepted;
  66. begin   

  67.     /// 不安装时的处理 : 退出安装程序                                    
  68.     if (g_bSetupNow == FALSE) then
  69.         abort;
  70.     endif;

  71.     // Added in InstallShield 15 - Show an appropriate error message if
  72.     // -removeonly is specified and the product is not installed.
  73.     if( REMOVEONLY ) then
  74.         Disable( DIALOGCACHE );
  75.         szMsg = SdLoadString( IDS_IFX_ERROR_PRODUCT_NOT_INSTALLED_UNINST );
  76.         SdSubstituteProductInfo( szMsg );
  77.         MessageBox( szMsg, SEVERE );
  78.         abort;
  79.     endif;

  80.     nSetupType = COMPLETE;  
  81.     szDir = TARGETDIR;
  82.     szName = "";
  83.     szCompany = "";
  84.     bLicenseAccepted = FALSE;

  85. // Beginning of UI Sequence
  86. Dlg_Start:
  87.     nResult = 0;

  88. Dlg_SdWelcome:
  89.     szTitle = "";
  90.     szMsg = "";
  91.     //{{IS_SCRIPT_TAG(Dlg_SdWelcome)
  92.     nResult = SdWelcome( szTitle, szMsg );
  93.     //}}IS_SCRIPT_TAG(Dlg_SdWelcome)
  94.     if (nResult = BACK) goto Dlg_Start;

  95. Dlg_SdLicense2:
  96.     szTitle = "";
  97.     szOpt1 = "";
  98.     szOpt2 = "";
  99.     //{{IS_SCRIPT_TAG(License_File_Path)
  100.     szLicenseFile = SUPPORTDIR ^ "License.rtf";
  101.     //}}IS_SCRIPT_TAG(License_File_Path)
  102.     //{{IS_SCRIPT_TAG(Dlg_SdLicense2)
  103.     nResult = SdLicense2Ex( szTitle, szOpt1, szOpt2, szLicenseFile, bLicenseAccepted, TRUE );
  104.     //}}IS_SCRIPT_TAG(Dlg_SdLicense2)
  105.     if (nResult = BACK) then
  106.         goto Dlg_SdWelcome;
  107.     else
  108.         bLicenseAccepted = TRUE;
  109.     endif;

  110. Dlg_SdRegisterUser:
  111.     szMsg = "";
  112.     szTitle = "";
  113.     //{{IS_SCRIPT_TAG(Dlg_SdRegisterUser)   
  114.     nResult = SdRegisterUser( szTitle, szMsg, szName, szCompany );
  115.     //}}IS_SCRIPT_TAG(Dlg_SdRegisterUser)
  116.     if (nResult = BACK) goto Dlg_SdLicense2;

  117. Dlg_SetupType2:   
  118.     szTitle = "";
  119.     szMsg = "";
  120.     nResult = CUSTOM;
  121.     //{{IS_SCRIPT_TAG(Dlg_SetupType2)   
  122.     nResult = SetupType2( szTitle, szMsg, "", nSetupType, 0 );
  123.     //}}IS_SCRIPT_TAG(Dlg_SetupType2)
  124.     if (nResult = BACK) then
  125.         goto Dlg_SdRegisterUser;
  126.     else
  127.         nSetupType = nResult;
  128.         if (nSetupType != CUSTOM) then
  129.             szTargetPath = TARGETDIR;
  130.             nSize = 0;
  131.             FeatureCompareSizeRequired( MEDIA, szTargetPath, nSize );
  132.             if (nSize != 0) then      
  133.                 MessageBox( szSdStr_NotEnoughSpace, WARNING );
  134.                 goto Dlg_SetupType2;
  135.             endif;
  136.         endif;   
  137.     endif;

  138. Dlg_SdAskDestPath2:
  139.     if ((nResult = BACK) && (nSetupType != CUSTOM)) goto Dlg_SetupType2;
  140.     szTitle = "";
  141.     szMsg = "";
  142.     if (nSetupType = CUSTOM) then
  143.                 //{{IS_SCRIPT_TAG(Dlg_SdAskDestPath2)   
  144.         nResult = SdAskDestPath2( szTitle, szMsg, szDir );
  145.                 //}}IS_SCRIPT_TAG(Dlg_SdAskDestPath2)
  146.         TARGETDIR = szDir;
  147.     endif;
  148.     if (nResult = BACK) goto Dlg_SetupType2;

  149. Dlg_SdFeatureTree:
  150.     if ((nResult = BACK) && (nSetupType != CUSTOM)) goto Dlg_SdAskDestPath2;
  151.     szTitle = "";
  152.     szMsg = "";
  153.     szFeatures = "";
  154.     nLevel = 2;
  155.     if (nSetupType = CUSTOM) then
  156.         //{{IS_SCRIPT_TAG(Dlg_SdFeatureTree)   
  157.         nResult = SdFeatureTree( szTitle, szMsg, TARGETDIR, szFeatures, nLevel );
  158.         //}}IS_SCRIPT_TAG(Dlg_SdFeatureTree)
  159.         if (nResult = BACK) goto Dlg_SdAskDestPath2;  
  160.     endif;

  161. Dlg_SQLServer:
  162.     nResult = OnSQLServerInitialize( nResult );
  163.     if( nResult = BACK ) goto Dlg_SdFeatureTree;

  164. Dlg_ObjDialogs:
  165.     nResult = ShowObjWizardPages( nResult );
  166.     if (nResult = BACK) goto Dlg_SQLServer;

  167. Dlg_SdStartCopy2:
  168.     szTitle = "";
  169.     szMsg = "";
  170.     //{{IS_SCRIPT_TAG(Dlg_SdStartCopy2)
  171.     nResult = SdStartCopy2( szTitle, szMsg );   
  172.     //}}IS_SCRIPT_TAG(Dlg_SdStartCopy2)
  173.     if (nResult = BACK) goto Dlg_ObjDialogs;

  174.     // Added in 11.0 - Set appropriate StatusEx static text.
  175.     SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_FIRSTUI ) );

  176.     return 0;
  177. end;
  178. //---------------------------------------------------------------------------
  179. // OnMaintUIBefore
  180. //
  181. // Maintenance UI Sequence - Before Move Data
  182. //
  183. // The OnMaintUIBefore event is called by OnShowUI when the setup is
  184. // running in maintenance mode. By default this event displays UI that
  185. // allows the end user to add or remove features, repair currently
  186. // installed features or uninstall the application.
  187. //
  188. // Note: This event will not be called automatically in a
  189. // program...endprogram style setup.
  190. //---------------------------------------------------------------------------
  191. function OnMaintUIBefore()
  192.     number  nResult, nType;
  193.     string  szTitle, szMsg;
  194. begin

  195.     /// 不安装时的处理 : 退出安装程序                          
  196.     if (g_bSetupNow == FALSE) then
  197.         abort;
  198.     endif;

  199.     // nType defaults to MODIFY.
  200.     nType = REPAIR; ///< 只有选修复, 才能实现覆盖安装

  201.     //Initialize SQL
  202.     OnSQLServerInitializeMaint();

  203. // Beginning of UI Sequence
  204. Dlg_Start:

  205.     // Added in Version 9.5 - Support for REMOVEONLY option.
  206.     if( !REMOVEONLY ) then
  207.         // In standard mode show maintenance dialog
  208.         Disable( BACKBUTTON );   
  209.         /// 不让用户选择, 直接进行"修复", 实现覆盖安装
  210.         // nType = SdWelcomeMaint( szTitle, szMsg, nType );
  211.         Enable( BACKBUTTON );
  212.         nResult = NEXT;
  213.     else
  214.         // Hide the initial progress dialog as otherwise the user can
  215.         // click on it, and hide the MessageBox.
  216.         Disable( DIALOGCACHE );

  217.         // In RemoveOnly mode, set to remove.
  218.         nType = REMOVEALL;
  219.     endif;

  220.     // Show Uninstall Confirmation Dialog
  221.     if ( nType = REMOVEALL ) then
  222.         nResult = MessageBox( SdLoadString( IFX_MAINTUI_MSG ), MB_YESNO );
  223.         if (nResult != IDYES ) then

  224.             if( REMOVEONLY ) then
  225.                 // In REMOVEONLY mode, abort the setup.
  226.                 abort;
  227.             else
  228.                 // In non-REMOVEONLY mode, redisplay the previous dialog.
  229.                 goto Dlg_Start;
  230.             endif;

  231.         endif;
  232.     endif;

  233. Dlg_SdFeatureTree:
  234.     if ( nType = MODIFY ) then
  235.         szTitle = "";
  236.         szMsg = SdLoadString( SD_STR_COMPONENT_MAINT_MSG );
  237.         nResult = SdFeatureTree( szTitle, szMsg, TARGETDIR, "", -1 );
  238.         if ( nResult = BACK ) goto Dlg_Start;
  239.     endif;

  240. Dlg_ObjDialogs:
  241.     nResult = ShowObjWizardPages( nResult );
  242.     if ( ( nResult = BACK ) && ( nType != MODIFY ) ) goto Dlg_Start;
  243.     if ( ( nResult = BACK ) && ( nType = MODIFY ) ) goto Dlg_SdFeatureTree;

  244.     switch(nType)

  245.         case REMOVEALL:

  246.             // Ensure that all previously installed features are removed.
  247.             FeatureRemoveAllInMediaAndLog();

  248.             // Added in 11.0 - Set appropriate StatusEx static text.
  249.             SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_MAINTUI_REMOVEALL ) );

  250.         case REPAIR:

  251.             // Changed for DevStudio 9, Disk1 files are now always updated when installed
  252.             // so when running from ADDREMOVE we need to prevent these files from being
  253.             // updated since this will result in files being updated that are locked by the setup.
  254.             // Updating these files when running from ADDREMOVE should not be needed since updates
  255.             // are not run directly from Add/Remove.
  256.             if( ADDREMOVE ) then
  257.                 // Reinstall all previously installed features, except
  258.                 // disk1 features.
  259.                 FeatureUpdate( "" );
  260.             else
  261.                 // Reinstall all previously installed features.
  262.                 FeatureReinstall();
  263.             endif;

  264.             // Added in 11.0 - Set appropriate StatusEx static text.
  265.             SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_MAINTUI_REPAIR ) );

  266.         case MODIFY:

  267.             // Added in 11.0 - Set appropriate StatusEx static text.
  268.             SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_MAINTUI_MODIFY ) );

  269.     endswitch;

  270. end;
  271. //---------------------------------------------------------------------------
  272. // OnMoveData
  273. //
  274. // The OnMoveData event is called by OnShowUI to initiate the file
  275. // transfer of the setup.
  276. //
  277. // Note: This event will not be called automatically in a
  278. // program...endprogram style setup.
  279. //---------------------------------------------------------------------------
  280. function OnMoveData()
  281. number  nResult, nMediaFlags;
  282. begin

  283.     // Don't install the DISK1COMPONENT if MAINT_OPTION_NONE was specified.
  284.     if( MAINT_OPTION = MAINT_OPTION_NONE ) then
  285.         FeatureSelectItem( MEDIA, DISK1COMPONENT, FALSE );
  286.     endif;

  287.     // Updated in 11.5, disable the cancel button during file transfer unless
  288.     // this is non-maintenance mode or repair mode.
  289.     if( MAINTENANCE && ( !REINSTALLMODE || UPDATEMODE ) ) then
  290.         Disable( CANCELBUTTON );
  291.     endif;

  292.     // Show Status
  293.     // Note: Start status window at 1 in case CreateInstallationInfo call
  294.     // is lengthy.
  295.     SetStatusWindow( 1, "" );
  296.     Enable( STATUSEX );
  297.     StatusUpdate( ON, 100 );

  298.     // Create the uninstall infomation (after displaying the progress dialog)
  299.     // Don't create uninstall information if MAINT_OPTION_NONE was specified.
  300.     if( MAINT_OPTION != MAINT_OPTION_NONE ) then
  301.         CreateInstallationInfo();
  302.     endif;

  303.     // Move Data
  304.     nResult = FeatureTransferData( MEDIA );

  305.     // Moved in 11.0, Check for failure before creating uninstall key.
  306.     // Handle move data error and abort if error occured.
  307.     if( nResult < ISERR_SUCCESS ) then
  308.         OnComponentError();
  309.         abort;
  310.     endif;      

  311.     // Create uninstall key, if DISK1COMPONENT was installed.
  312.     if( IFX_DISK1INSTALLED ) then

  313.         // Store text-subs for maintenance mode later, only do this when
  314.         // disk 1 is installed. Note that any text-subs that are updated after
  315.         // this call will not be remembered during maintenance mode.
  316.         FeatureSaveTarget("");

  317.         // Write uninstall information.
  318.         MaintenanceStart();

  319.         // Customize Uninstall Information
  320.         OnCustomizeUninstInfo();

  321.     endif;

  322.     // Disable Status
  323.     Disable( STATUSEX );

  324. end;
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SgzyStudio

GMT+8, 2024-5-19 18:23 , Processed in 0.099542 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表