InstallShield12 添加自定义对话框,并根据输入值修改对应的Config文件。

直接图文:注:

使用的模板为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, 完成。

 

posted @ 2012-05-29 11:25  YFeng_Lee  阅读(4794)  评论(1编辑  收藏  举报