Thursday, December 20, 2012

InstallShield 2010 - Dynamically update App Config File



In this blog, I will show you how to let user update app config file during installation.
I assume that you know how to add custom dialog to InstallScript Project.

-          In the Custom Dialog, we add 2 Edit Fields (TextBox) to input ContactName and Address. Give them 2 Control Identifiers 1988 and 1989.
-          Go back to the ShopInfoDialog function to make some changes.
o   Add parameters to keep the user value.
o   Handle Edit action.

// Add Define Id for edit fields
#define BTN_NEXT                        1
#define BTN_BACK                       12
#define BTN_CANCEL                  9
#define EDIT_CONTACTNAME   1988   
#define EDIT_ADDRESS                1989                        
                
//2 parameter for Contact and Address, using byref to take it out
prototype NUMBER ShopInfoDialog(byref string , byref string);

function NUMBER ShopInfoDialog(szContact, szAddress)  
                string                     szDlg;
                number                nReturn, nControl, nMessage, nResult;  
                HWND                  hwndDlg, hwndNext;   
                BOOL                     bDone;
begin            
    //keep the name in constant
                szDlg = "ShopInfoDialog";
               
                //regist the Dialog
            nReturn = EzDefineDialog(szDlg, // nickname dialog                                                       
                          "", // DLL containing the dialog’s resources         
                          "",           // name of dialog in Dialogs view
                         10); // numeric resource ID for dialog; not used here    
                                                                                                               
                if (nReturn == DLG_ERR) then
                                return -1;
                endif;
               
                bDone = FALSE;
              
 while (!bDone)
                nControl = WaitOnDialog(szDlg);      
                if (nControl = -1) then
                    MessageBox("Dialog initialize -1 --> ERROR",INFORMATION);
                    abort;
                endif;
 switch (nControl)    
       case DLG_INIT:
            // set init data                                
            //init value for edit fields
                CtrlSetText( szDlg, EDIT_CONTACTNAME,            szContact );
                CtrlSetText( szDlg, EDIT_ADDRESS,                            szAddress);
            //get handle of this Dlg and Next button
 hwndDlg = CmdGetHwndDlg( szDlg );
                hwndNext = CtrlGetDlgItem("",  hwndDlg, NEXT );
                SdGeneralInit( szDlg, hwndDlg, STYLE_BOLD, szSdProduct );
          
//Enable Next Button if only data was filled
EnableWindow( hwndNext, StrLengthChars( szContact ) && StrLengthChars( szAddress ));
           
case EDIT_CONTACTNAME:
nMessage = CtrlGetSubCommand(szDlg);
if (nMessage = EDITBOX_CHANGE) then
    //set  szContact by the value of EDIT_CONTACTNAME control
CtrlGetText(szDlg, EDIT_CONTACTNAME, szContact);
//trim
StrTrim( szContact );   
StrTrim( szAddress );   
//set Enable of Next button
                  EnableWindow( hwndNext, StrLengthChars( szContact ) && StrLengthChars( szAddress ));    
            endif;                       
case EDIT_ADDRESS:
nMessage = CtrlGetSubCommand(szDlg);
if (nMessage = EDITBOX_CHANGE) then               
CtrlGetText(szDlg, EDIT_ADDRESS, szAddress);
StrTrim( szContact );   
StrTrim( szAddress );   
                   EnableWindow( hwndNext, StrLengthChars( szContact ) && StrLengthChars( szAddress ));  
            endif;                       

case BTN_BACK:
        // user clicked Back
                        nReturn = BTN_BACK;
                        bDone = TRUE;
case BTN_NEXT: 
        // user clicked Next      
                        nReturn = BTN_NEXT;
                        bDone = TRUE;
case BTN_CANCEL:
        // user clicked Cancel; ask user to verify cancellation
                        Do(EXIT);
endswitch;

endwhile;    
 
  EndDialog( szDlg );
  ReleaseDialog( szDlg ); 
 
return nControl;
end;

Next, we will import our App Config File.
-          Under System Configuration, choose XML File Changes.


-          At the XML Files tree, right click and import for config file. In my sample, there is only appSetting section with 2 keys.
-          For each key, give the Value Property a FieldName in ”<” and “>”. This will help us replace the text.

-          Now, go back to the OnFirstUIBefore function.
-          Declare 2 strings szContact and szAddress.
-          Go to the lable Dlg_SdEnterShopInfomation and update the block code as:

Dlg_SdEnterShopInfomation:
    //{{IS_SCRIPT_TAG(Dlg_SdEnterShopInfomation)           
    nResult = ShopInfoDialog(szContact, szAddress);
    //}}IS_SCRIPT_TAG(Dlg_SdEnterShopInfomation)
    if (nResult = BACK) then      
                goto Dlg_SdRegisterUser;  
    endif;
    if (nResult = NEXT) then      
                //Globally set <Property> to custom value
                TextSubSetValue("<ContactValue>", szContact, TRUE);    
                TextSubSetValue("<AddressValue>", szAddress, TRUE);    
    endif;

Build, Run and find the config file at Application Target Folder.

Installshield 2010 - Add Custom Dialog


In this blog, I will show how to make a Custom Dialog and add it in the installation sequence.
The version of Installshield is 2010 Version 16.
Let’s start to create a InstallScript Project. The Basic MSI Project could also do this task but it give you very limited options later.

To create a Dialog:

-  In the Installation Designer tree, under User Interface, choose Dialogs.
- In the list of Dialogs, right click on All Dialog and choose New Dialogs.
- I will try a NewScriptBasedDialog, give it a name, “ShopInfoDialog” for example.
  Click Finish.

-   Now you see your new dialog display in bold. Expand it and choose English (United State) to go to design view.
-      Your dialog will initially blank and have 3 main buttons: Back Next Cancel.
-      Go to the Property Panel on the right; give the Resource Identifier a unique number value. I will try 10.
-      Add some controls as your need. You can just leave it blank.
Next, I will create the dialog function.
-      In the Installation Designer tree, under Behavior and Logic, choose InstallScript.
-      In the Installscript tree, you will see only the Setup.Rul available.
-      For our dialog, please create a new script file. Let’s name it shopinfodialog.rul
-      Create a function to open our dialog.
//These are button ids
#define BTN_NEXT              1
#define BTN_BACK              12
#define BTN_CANCEL           9
                 
prototype NUMBER ShopInfoDialog();
function NUMBER ShopInfoDialog()  
        string         szDlg;
        number      nReturn, nControl, nMessage, nResult;  
        HWND       hwndDlg, hwndNext;   
        BOOL        bDone;
begin
end
-      In the body, we will display the dialog and handle button controls.
begin
              
//keep the name in constant
        szDlg = "ShopInfoDialog";    
//regist the Dialog
        nReturn = EzDefineDialog(szDlg, // nickname for dialog                                                       
                                "", // DLL containing the dialog’s resources 
                                "",     // name of dialog in Dialogs view
                                10); // numeric resource ID for dialog; not used here    
                                                       
        if (nReturn == DLG_ERR) then
                return -1;
        endif;
       
        bDone = FALSE;
              
 while (!bDone)
        nControl = WaitOnDialog(szDlg);      
        if (nControl = -1)then
                MessageBox("Dialog initialize -1 ----> ERROR",INFORMATION);
                abort;
        endif;
        switch (nControl)    
                case DLG_INIT:
                //get handle of this Dlg and Next button
            hwndDlg = CmdGetHwndDlg( szDlg );
            hwndNext = CtrlGetDlgItem("",  hwndDlg, NEXT );
            SdGeneralInit( szDlg, hwndDlg, STYLE_BOLD, szSdProduct );
        case BTN_BACK:
        // user clicked Back
                nReturn = BTN_BACK;
                bDone = TRUE;
        case BTN_NEXT: 
        // user clicked Next      
                nReturn = BTN_NEXT;
                bDone = TRUE;
        case BTN_CANCEL:
        // user clicked Cancel; ask user to verify cancellation
                Do(EXIT);
        endswitch;
  endwhile;    
 
  EndDialog( szDlg );
  ReleaseDialog( szDlg );  
 
  return nControl;
end;

-      Now, the dialog is ready to use.

Next, I will add the dialog in the sequence after the User Information Dialog.

-      For more information, the User Information Dialog usually comes after the License Agreement Dialog where you could enter Name and Company.
-      Go back to the InstallScript View. On the ComboBox which current select “Initialization”, select “Before move data”.
-      On the drop down next to the right, find OnFirstUIBefore. That will bring out the function where you edit the first install sequence.



-      Each Dialog in the sequence is implemented under each Label. Now find the Dlg_SdRegisterUser. Add our code right after this block.
Dlg_SdEnterShopInfomation:
    //{{IS_SCRIPT_TAG(Dlg_SdEnterShopInfomation)           
    nResult = ShopInfoDialog();
    //}}IS_SCRIPT_TAG(Dlg_SdEnterShopInfomation)
    if (nResult = BACK) then  
        goto Dlg_SdRegisterUser;
    endif;
-      Now Build and Run.