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 field 111 StrTrim( svPort ); 112 StrTrim( svPwd ); 113 StrTrim(svClosePort); 114 bsuccess=TRUE; 115 // if any of the fields are empty, disable the Next button 116 if(svPwd = "" || svPort = ""||svClosePort="" ) then 117 bsuccess=FALSE; 118 else 119 //the svPort max length is 5,and must be number 120 if((StrToNum(nVar,svPort)<0)||(StrToNum(nVar,svClosePort)<0)) then 121 bsuccess=FALSE; 122 else 123 if((StrLength(svPort)>5)||(StrLength(svClosePort)>5)) then 124 bsuccess=FALSE; 125 else if(svPort= svClosePort) then 126 bsuccess=FALSE; 127 endif; 128 endif; 129 endif; 130 //the svPwd max length is 8 131 if(StrLength(svPwd)>8) then 132 bsuccess=FALSE; 133 endif; 134 endif; 135 EnableWindow( hwndItem, bsuccess ); 136 end;
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 allowing 10 // 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) then 52 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 status 59 Enable(STATUSEX); 60 61 return 0; 62 end;
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