直接圖文:注:
使用的模板為InstallScript MSI Project
Installation Designer -->User Interface -->Dialogs -- >All Dialogs -->右鍵 New Dialog -- >下一步 NewScriptBasedDialog
圖1:
雙擊自定義的對話框,進入對話框設計器,然后通過設計器來繪制自定義對話框。
圖2:
圖3:
View -->Maximize 使設計器最大化
此時要注意幾個屬性值:1 點擊窗體,顯示右側屬性 Resource Identifier需要根據需要自己定義,此值會在代碼中使用到。需特別注意。為防止與其他的Id沖突,可設置較大一點,其后的ID會根據此ID自動遞增。
圖4:
新建一個field,其Control Identifier值會根據Resource Identifier自增(窗體的Id叫 Resource Identifier,而field的Id就稱為Control Identifier)然后根據實際需要設計窗體布局。以下為設計好的對話框。
圖5:
好,現在界面部分已經完成,需要進入腳本操作。
圖6:
選擇Setup.Rul --> Before Move Data -- OnFirstUIBefore.
注意此函數在InstallScript MSI Project 中是用來控制對話框的顯示順序,同時可以將自定義的窗體插入到顯示序列中。
圖7:
代碼如下
function OnFirstUIBefore()
NUMBER nResult, nSetupType, nvSize, nUser;
STRING szTitle, szMsg, szQuestion, svName, svCompany, szFile;
STRING szLicenseFile;
LIST list, listStartCopy;
BOOL bCustom;
begin
// TO DO: if you want to enable background, window title, and caption bar title
// SetTitle( @PRODUCT_NAME, 24, WHITE );
// SetTitle( @PRODUCT_NAME, 0, BACKGROUNDCAPTION );
// Enable( FULLWINDOWMODE );
// Enable( BACKGROUND );
// SetColor(BACKGROUND,RGB (0, 128, 128));
SHELL_OBJECT_FOLDER = @PRODUCT_NAME;
nSetupType = TYPICAL;
Dlg_SdWelcome:
szTitle = "";
szMsg = "";
nResult = SdWelcome(szTitle, szMsg);
if (nResult = BACK) goto Dlg_SdWelcome;
szTitle = "";
svName = "";
svCompany = "";
Dlg_SdCustomerInformation:
nResult = SdCustomerInformation(szTitle, svName, svCompany, nUser);
if (nResult = BACK) goto Dlg_SdWelcome;
Dlg_SetupType:
szTitle = "";
szMsg = "";
nResult = SetupType(szTitle, szMsg, "", nSetupType, 0);
if (nResult = BACK) then
goto Dlg_SdCustomerInformation;
else
nSetupType = nResult;
if (nSetupType != CUSTOM) then
nvSize = 0;
FeatureCompareSizeRequired(MEDIA, INSTALLDIR, nvSize);
if (nvSize != 0) then
MessageBox(szSdStr_NotEnoughSpace, WARNING);
goto Dlg_SetupType;
endif;
bCustom = FALSE;
goto Dlg_SQL;
else
bCustom = TRUE;
endif;
endif;
Dlg_SdAskDestPath:
nResult = SdAskDestPath(szTitle, szMsg, INSTALLDIR, 0);
if (nResult = BACK) goto Dlg_SetupType;
Dlg_SdFeatureTree:
szTitle = "";
szMsg = "";
if (nSetupType = CUSTOM) then
nResult = SdFeatureTree(szTitle, szMsg, INSTALLDIR, "", 2);
if (nResult = BACK) goto Dlg_SdAskDestPath;
endif;
Dlg_SQL:
nResult = OnSQLLogin( nResult );
if( nResult = BACK ) then
if (!bCustom) then
goto Dlg_SetupType;
else
goto Dlg_SdFeatureTree;
endif;
endif;
Dlg_ChangeConfig:
nResult = ChangeConfig("", "" );
if( nResult = BACK ) then
goto Dlg_SQL;
endif;
Dlg_SdStartCopy:
szTitle = "";
szMsg = "";
listStartCopy = ListCreate( STRINGLIST );
//The following is an example of how to add a string(svName) to a list(listStartCopy).
//eg. ListAddString(listStartCopy,svName,AFTER);
nResult = SdStartCopy( szTitle, szMsg, listStartCopy );
ListDestroy(listStartCopy);
if (nResult = BACK) then
goto Dlg_SQL;
endif;
// setup default status
Enable(STATUSEX);
return 0;
end;
代碼解釋:
Dlg_ChangeConfig:
nResult = ChangeConfig("", "" );
if( nResult = BACK ) then
goto Dlg_SQL;
endif;
這段是自己添加的自定義代碼,作用是在窗體Dlg_SQL完成后,顯示自定義窗體(名稱為ChangeConfig)
nResult = ChangeConfig("", "" );
ChangeConfig是自定義的函數,定義及實現如下:
首先需要在代碼的頭位置定義函數:
export prototype ChangeConfig(string, string);
然后 定義函數體:
function ChangeConfig(szTitle, szMsg)
string szDlg, szDialogName, szDLLName, szDialog;
number nId, hInstance, hwndParent, nResult;
HWND hwndDlg;
BOOL bDone;
begin
// Specify a name to identify the custom dialog in this installation.
szDlg = "ChangeConfig";
// ensure general initialization is complete
if( !bSdInit ) then
SdInit();
endif;
szDialogName = "NewDialog";
hInstance = 0;
szDLLName = "";
szDialog = "";
hwndParent = 0;
//szDlg是自定義窗體的名稱(參見圖1), 10000為此窗體的Resource Identifier.
nResult = EzDefineDialog(szDlg, ISUSER, "", 10000 );
// Initialize the indicator used to control the while loop.
bDone = FALSE;
// Loop until done.
while (!bDone)
// Display the dialog and return the next dialog event.
nId = WaitOnDialog(szDlg);
// Respond to the event.
switch(nId)
case DLG_INIT:
// No initialization is required for this example.
case NEXT:
getCtrlText();
nId = NEXT;
bDone = TRUE;
case BACK:
nId = BACK;
bDone = TRUE;
case DLG_ERR:
SdError( -1, "Errrrrrrr" );
nId = -1;
bDone = TRUE;
case DLG_CLOSE:
SdCloseDlg( hwndDlg, nId, bDone );
default:
// check standard handling
if(SdIsStdButton( nId ) && SdDoStdButton( nId )) then
bDone = TRUE;
endif;
endswitch;
endwhile;
// Cleanup Dialog
EndDialog( szDlg );
ReleaseDialog( szDlg );
SdUnInit();
// record data produced by this dialog
if( MODE = RECORDMODE ) then
endif;
return nId;
end;
代碼注釋:
case NEXT:
getCtrlText();
nId = NEXT;
bDone = TRUE;
即在窗體點擊下一步時執行自定義的代碼。
getCtrlText代碼如下
prototype getCtrlText();
export prototype FNModifyProperty(string, int, string);
#define DLG_SERVICEIP_ID 10001
#define DLG_WEBIP_ID 10009
#define DLG_MAILSERVERIP_ID 10011
#define DLG_MAILPORT_ID 10017
#define DLG_ENABLESSL_ID 10024
#define DLG_MAILUSER_ID 10020
#define DLG_MAILPWD_ID 10019
#define DLG_MAILADMINADDRESS_ID 10021
#define DLG_TARGETENV_ID 10028
#define DLG_TARGETENVNAME_ID 10029
function getCtrlText()
string szDialogName, svUser, strRtn;
begin
szDialogName = "ChangeConfig";
//ServiceIP
FNModifyProperty(szDialogName, DLG_SERVICEIP_ID, "C_SERVICEIP");
//WebIP
FNModifyProperty(szDialogName, DLG_WEBIP_ID, "C_WEBIP");
//C_MAILSERVERIP
FNModifyProperty(szDialogName, DLG_MAILSERVERIP_ID, "C_MAILSERVERIP");
//C_MAILPORT
FNModifyProperty(szDialogName, DLG_MAILPORT_ID, "C_MAILPORT");
//ServiceIP
FNModifyProperty(szDialogName, DLG_ENABLESSL_ID, "C_ENABLESSL");
//WebIP
FNModifyProperty(szDialogName, DLG_MAILUSER_ID, "C_MAILUSER");
//C_MAILSERVERIP
FNModifyProperty(szDialogName, DLG_MAILPWD_ID, "C_MAILPWD");
//C_MAILPORT
FNModifyProperty(szDialogName, DLG_MAILADMINADDRESS_ID, "C_MAILADMINADDRESS");
//ServiceIP
FNModifyProperty(szDialogName, DLG_TARGETENV_ID, "C_TARGETENV");
//WebIP
FNModifyProperty(szDialogName, DLG_TARGETENVNAME_ID, "C_TARGETENVNAME");
end;
function FNModifyProperty(szDialogName, id, propertyId)
string tempStr;
begin
CtrlGetText(szDialogName, id, tempStr);
//MessageBox(tempStr, INFORMATION);
MsiSetProperty(ISMSI_HANDLE,propertyId,tempStr);
end;
代碼注釋
DLG_XXXX_ID為圖5的文本框的Id.
可以注意到,代碼中關鍵的一個方法是FNModifyProperty,此方法的目的是為了將文本框的值,賦給自定義屬性(可以理解為IS的全局變量,此變量可以在后面的XML變更時,被引用到)。
屬性的定義如下:
C_XXXX與圖5的文本框一一對應,即在自定義文本框點擊下一步時,將文本框的值賦給全局變量C_XXXX。注:文本框的值只在OnFirstUIBefore方法的對應顯示窗體的步驟中才能夠獲取到。
此時自定義的窗體的值已經被保存到IS的可訪問屬性(全局變量)中, 下面就是對此屬性值的應用了。我們獲取這些屬性的目的主要是為了修改我們應用程序的配置文件信息。以下將演示如何引入Config,並將Config的值用屬性值進行替換。
SystemConfiguration -->XML Files Changes
選擇右側的 XML Fiels,右鍵 Import(導入)
選擇需要變更的節點。
選擇文件名, 修改此配置文件在安裝環境的目錄。
然后選擇到對應的節點。
然后將需要修改的部分如192.168.0.116替換為[C_SERVICEIP]([]表示屬性,IS會在生成時自動將[xxxx]用xxxx的屬性值替換)
最后,切換到Advanced,將Set element content選項選中。
最后編譯生成安裝包,然后在目標環境運行安裝包。
安裝完畢后,會看到對應的配置文件會根據填寫的值自動修改。
OK, 完成。