首页 > 代码库 > Installshield实例(二)创建自定义界面

Installshield实例(二)创建自定义界面

Installshield MSI Project项目。

需求:

在安装过程中需要一个界面让用户输入一些特定的信息,但installshield自带的界面无法满足要求,需要我们自己新建一个界面。

原理:

1、在Installation Desigenr->User Interface->Dialog中,我们可以新建Dialog即界面,每个Dialog对应一个Resource identified即ID,该Resource ID是唯一的,用以得到对应的Dialog界面,即你以后在InstallScript中写代码时,即通过该Resource id获取该界面。

2、Dialog界面上的控件,即输入框,按钮等,都有一个Control identified与之定义,该ID也是为了获取该界面上的控件,此后便通过ID获取相应的控件。

3、界面设计好以后,需要编写相对应的.rul结尾的script文件,用于编写界面上不同控件的事件,例如:校验密码等。

4、在Setup.Rul中适当的位置调用该界面即可。

实例:

Installshield安装文件中自带了一个实例,在安装路径:$InstallShield\2010\Samples\InstallScript下有一个Serial Number Validation Sample Project文件夹,用InstallShield打开Serial Number Validation Sample Project.ism即可,该例子主要用于验证用户输入的序列号,正确即可点击下一步,否则下一步不允许点,在此,我另建一个Dialog,自带的实例,自行查看。

1、点击Installation Desigenr->User Interface->Dialog,在All Dialog中右击,点击NEW Dialog,创建一个新的界面,取名为CustomSetInfo。

2、通过工具栏设置需要的界面。

 

3、点击该Dialog,右侧属性框中Resource Identified必须是唯一的,一般新建时会自动生成。

4、每个控件在绘制时,也会自动生成Control Identified的值,用于在此后的代码中通过该ID获取相应的控件。

5、注意:有一些控件的Control Identified是固定的,例如“上一步”,“下一步”等。

上述红框标识的必须和其他的一样,具体的值可以打开其他的Dialog查看,最直接的办法即打开其他的Dialog直接复制粘贴这几个控件即可。

6、绘制完界面之后,就要开始编写相对应的事件脚步了,在Installation Desigenr->Behavior and Logic->InstallScript,在右侧InstallScript的Files中右击创建一个customsetinfo.rul文件编写脚步事件。

  1 #define DLG_NAME "CustomSetInfo"    //Dialog名称  2 #define DLG_RESOURCEID 22222        //Dialog的Resource Identified  3 #define EDIT_BANKPORT  1306         //端口输入框控件Control Identified  4 #define EDIT_MYSQLPWD  1309         //密码输入框Control Identified  5 #define EDIT_BANKCLOSEPORT 1311     //关闭端口输入框控件Control Identified  6                                                                 7 //声明函数                                                                8 prototype SetInfo(BYREF STRING,BYREF STRING,BYREF STRING,BYREF STRING);  9 //根据用户的输入判断“下一步”是否可操作 10 prototype EnableNextButton(INT,INT,BYREF STRING,BYREF STRING,BYREF STRING); 11 function SetInfo(szMsg,svPort,svClosePort,svPwd) 12     STRING  szDlg, szTemp; 13     BOOL    bDone; 14     NUMBER  nId, nMessage, nTemp, nSdDialog, nSdCustomRegisterUserEx; 15     HWND    hwndDlg, hwndControl; 16 begin   17     szDlg = DLG_NAME; 18     nSdDialog = DLG_RESOURCEID; 19      20     // ensure general initialization is complete 21    if (!bSdInit) then 22       SdInit( ); 23    endif;  24    //初始化Dialog 25    if (EzDefineDialog( szDlg, "", "", DLG_RESOURCEID ) = DLG_ERR) then 26         return -1; 27    endif; 28    // Loop in dialog until the user selects a standard button 29    bDone = FALSE; 30    while (!bDone) 31          //Dialog界面中每一个操作均会触发该事件,返回控件的Control Identified 32       nId = WaitOnDialog( szDlg ); 33       switch(nId) 34       case DLG_INIT://第一次打开该界面时执行  35            if( szMsg != "" ) then 36                SdSetStatic( szDlg, SD_STA_MSG, szMsg ); 37            endif;                                   38            //将参数设置到控件中,即显示默认值 39            CtrlSetText(szDlg,EDIT_BANKPORT,svPort);  40            CtrlSetText(szDlg,EDIT_BANKCLOSEPORT,svClosePort); 41            CtrlSetText(szDlg,EDIT_MYSQLPWD,svPwd); 42            hwndDlg = CmdGetHwndDlg( szDlg ); 43            SdGeneralInit( szDlg, hwndDlg, STYLE_BOLD, szSdProduct ); 44            EnableNextButton( hwndDlg, NEXT, svPort,svClosePort,svPwd); 45             46       case EDIT_BANKPORT: 47            nMessage = CtrlGetSubCommand( szDlg ); 48            if( nMessage = EDITBOX_CHANGE ) then 49                CtrlGetText( szDlg, EDIT_BANKPORT, svPort ); 50            endif; 51            EnableNextButton( hwndDlg, NEXT, svPort,svClosePort,svPwd);  52             53       case EDIT_BANKCLOSEPORT: 54            nMessage = CtrlGetSubCommand( szDlg ); 55            if( nMessage = EDITBOX_CHANGE ) then 56                CtrlGetText( szDlg, EDIT_BANKCLOSEPORT, svClosePort ); 57            endif; 58            EnableNextButton( hwndDlg, NEXT, svPort,svClosePort,svPwd);   59             60       case EDIT_MYSQLPWD: 61            nMessage = CtrlGetSubCommand( szDlg ); 62            if( nMessage = EDITBOX_CHANGE ) then 63                CtrlGetText( szDlg, EDIT_MYSQLPWD, svPwd ); 64            endif; 65           EnableNextButton( hwndDlg, NEXT, svPort,svClosePort,svPwd); 66            67       case NEXT: 68            nId    = NEXT; 69            bDone  = TRUE; 70  71       case BACK: 72            nId    = BACK; 73            bDone  = TRUE; 74  75       case DLG_ERR: 76            SdError( -1, "CustomSetInfo" ); 77            nId    = -1; 78            bDone  = TRUE; 79  80       case DLG_CLOSE: 81            SdCloseDlg( hwndDlg, nId, bDone ); 82  83       default: 84            // check standard handling 85            if (SdIsStdButton( nId ) && SdDoStdButton( nId )) then 86                bDone = TRUE; 87            endif; 88       endswitch; 89  90    endwhile; 91  92    EndDialog( szDlg ); 93    ReleaseDialog( szDlg ); 94  95    SdUnInit( ); 96  97    return nId; 98  99 end;100 101 function EnableNextButton(hwndDlg,nControlID, svPort,svClosePort, svPwd )102     HWND hwndItem; 103     NUMBER nVar;104     BOOL bsuccess;105     begin 106        hwndItem = CtrlGetDlgItem( "", hwndDlg, nControlID );107     108        if (!IsWindow(hwndItem)) then return FALSE; endif;109     110        // trim trailing spaces from each field111        StrTrim( svPort );112        StrTrim( svPwd );113        StrTrim(svClosePort);114        bsuccess=TRUE;115        // if any of the fields are empty, disable the Next button116        if(svPwd = "" || svPort = ""||svClosePort="" ) then117           bsuccess=FALSE;118        else 119              //the svPort max length is 5,and must be number120           if((StrToNum(nVar,svPort)<0)||(StrToNum(nVar,svClosePort)<0)) then121                   bsuccess=FALSE;122           else  123                   if((StrLength(svPort)>5)||(StrLength(svClosePort)>5)) then124                       bsuccess=FALSE;  125                   else if(svPort= svClosePort) then126                       bsuccess=FALSE;  127                       endif;128                   endif;129           endif;130           //the svPwd max length is 8131           if(StrLength(svPwd)>8) then132                   bsuccess=FALSE;133           endif;    134        endif; 135       EnableWindow( hwndItem, bsuccess ); 136 end;
CustomSetInfo

7、在Setup.Rul中使用

 1 // Included header files ----------------------------------------------------    2 STRING szBankPort,szBankClosePort,szMysqlPwd; 3 #include "ifx.h"  4 #include "customsetinfo.rul"  //引入文件 5  6 // OnFirstUIBefore 7 // 8 // The OnFirstUIBefore event is called by the framework when the setup is 9 // running in first install mode. By default this event displays UI allowing10 // the end user to specify installation parameters.11 //---------------------------------------------------------------------------12 function OnFirstUIBefore()13     NUMBER nResult, nSetupType, nvSize, nUser;14     STRING szTitle, szMsg, szQuestion, svName, svCompany, szFile;15     STRING szLicenseFile;16     BOOL   bCustom, bIgnore1, bIgnore2; 17     STRING svResult; 18     NUMBER ISsucc,svSize,svType; 19     STRING mysqlpath,mysqlkey,jdkkey;    20 begin    21    22     nResult = 0;23     nSetupType = CUSTOM;    24         25 Dlg_SdWelcome:26     szTitle = "";27     szMsg   = "";28     nResult = SdWelcome(szTitle, szMsg);29     if (nResult = BACK) goto Dlg_SdWelcome;      30     szTitle   = "";31     svName    = "";32     svCompany = "";     33 34 Dlg_SdAskDestPath:        35     nResult = SdAskDestPath(szTitle, szMsg, INSTALLDIR, 0);36     if (nResult = BACK) goto Dlg_SdWelcome;37                                                    38 Dlg_SetInfo:  39     szMsg   = ""; 40     szBankPort="8101";41     szBankClosePort="8102";42     szMysqlPwd="";43     nResult=SetInfo(szMsg,szBankPort,szBankClosePort,szMysqlPwd); //使用新创建的界面44     if(nResult=BACK) goto Dlg_SdAskDestPath;  45                                             46 Dlg_SdStartCopy:47     szTitle = "";48     szMsg   = "";49     nResult = SdStartCopy2( szTitle, szMsg );            50     51     if (nResult = BACK) then52        goto Dlg_SetInfo;53     endif;54 55     // Added in IS 2009 - Set appropriate StatusEx static text.56     SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_FIRSTUI ) );57 58     // setup default status59     Enable(STATUSEX);60  61     return 0;62 end;
Setup

8、注册表操作

 1   //向注册表中添加本产品的安装路径和版本 2     svSize=-1;  3     svType=REGDB_STRING;    4     RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE);  5     bankKey="SOFTWARE\\UFGOVBank"; 6     if(RegDBKeyExist(bankKey)<0) then 7         RegDBCreateKeyEx(bankKey,""); 8     endif; 9     location = TARGETDIR;10     currentVersion = IFX_PRODUCT_VERSION;11     RegDBSetKeyValueEx ( bankKey, "location", svType, location, svSize ); 12     RegDBSetKeyValueEx ( bankKey, "CurrentVersion", svType, currentVersion, svSize ); 13     14 15     //删除注册表信息 16     RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE); 17     bankKey="SOFTWARE\\UFGOVBank\\";    18     RegDBDeleteKey(bankKey);
注册表操作

9、创建“卸载快捷方式”

 1     //创建卸载快捷键 2     szfilename = UNINSTALL_STRING +" /UNINSTALL"; 3     nresult = StrFind(szfilename,".exe"); 4     if nresult >=0 then 5         StrSub(szmsg1,szfilename,0,nresult + 4); 6         StrSub(szmsg2,szfilename,nresult + 4,200); 7         LongPathToQuote(szmsg1, FALSE ); 8         LongPathToQuote(szmsg2, FALSE ); 9         szfilename = "\""+szmsg1+"\""+szmsg2;10     endif;11     AddFolderIcon(FOLDER_PROGRAMS^"产品1","卸载产品1",szfilename,WINDIR,"",0,"",REPLACE);    12 13 14 15 //删除快捷方式16     DeleteProgramFolder(FOLDER_PROGRAMS^"产品1");17     
卸载快捷方式

Installshield实例(二)创建自定义界面