InstallShield Tips and Techniques

January 19, 2011

How to verify Feature selection within an InstallScript Custom Action

Filed under: Reference Materials — shieldmaster @ 1:42 am

I have a requirement to determine within an InstallScript Custom Action, when an application feature has been selected. Essentially there is a lot of discussion how you can set a condition based on Feature selection to launch a Custom Action – but very little regarding how to script logic to determine whether a feature was selected during the installation.

For example, here is a sample of a Custom Setup screen with Features and sub-features:

Nothing complicated, but I have a unique dialog screen “Software Prerequisites” that will display whether specific software prerequisites have been installed on the workstation – if they have not been installed, then I need to prevent the installation from continuing. Here is a sample showing how the NEXT button is disabled because Microsoft Office/Excel was not installed.

 

Now realistically, what if the sub-feature “Client Server 2” was a Feature that when selected will require that Microsoft Office, Excel and the Office Primary Interop Assemblies be present? Obviously, only when this feature is selected by the user should the dialog “Software Prerequisites” allow the installation to be failed if they are not installed. If the customer did not select “Client Server 2” for installation, then we can safely ignore the fact that Microsoft Office was not installed.

The scripting should be relatively simple? Well I initially thought so – but it’s turned out harder that I imagined!

Here is how I was able to get the script to function as I required:

  1. Create a InstallScript function – here is some script for evaluation:

    nReturnCode = MsiGetFeatureState (ISMSI_HANDLE, "CS2", nvInstallState, nvActionState); 

       switch (nvActionState)

        case INSTALLSTATE_ADVERTISED:    

            szString = "The advertised feature";

            MessageBox ("C2 state is:" + szString, INFORMATION);

        case INSTALLSTATE_ABSENT:

            szString = "The feature was uninstalled";

            MessageBox ("C2 state is:" + szString, INFORMATION);

        case INSTALLSTATE_LOCAL:

            szString = "The feature was installed on the local drive";

            MessageBox ("C2 state is:" + szString, INFORMATION);

        case INSTALLSTATE_SOURCE:

            szString = "The feature must run from the source, CD-ROM, or network";

            MessageBox ("C2 state is:" + szString, INFORMATION);

        case INSTALLSTATE_DEFAULT:

            szString = "The feature is installed in the default location: local or source";

            MessageBox ("C2 state is:" + szString, INFORMATION);

        case INSTALLSTATE_UNKNOWN:

            szString = "An unrecognized product or feature was specified";   

            MessageBox ("C2 state is:" + szString, INFORMATION);

        case INSTALLSTATE_SOURCEABSENT:

            szString = "The feature must run from the source, and the source is unavailable.";

            MessageBox ("C2 state is:" + szString, INFORMATION);

        case INSTALLSTATE_INCOMPLETE:

            szString = "The installation is suspended or in progress";

            MessageBox ("C2 state is:" + szString, INFORMATION);

        default:

            szString = "The return code is not supported";

            MessageBox ("C2 state is:" + szString, INFORMATION);

        endswitch;

 

 

Notes: 

  1. Here is how the InstallShield GUI displays the Features - for scripting to reference a Feature, you need to use the feature name "CS2" - not the Description, which would be what is displayed in the Custom Section dialog - "Client Server 3"
    

 

        
			

 

 

  1. Create a InstallScript Custom Action, referencing the InstallScript function. In my situation, I called the Custom Action using a “DoAction” on the NEXT button of the Custom Setup dialog.

     

    Here is what happens when the script executes Immediately after the NEXT button is pressed for the Custom Action:

    1. When Feature “CS3” is selected by the user – the script case “ INSTALLSTATE_LOCAL” is activated.
    2. When Feature “CS3” is not selected by the user – the script case “ INSTALLSTATE_UNKNOWN ” is activated.

       

  2. If you create a InstallScript Custom Action, referencing the InstallScript function – and set the Custom Action’s In-Script execution as “Immediate”, but run the CA in the Execute Sequence – just before the files are installed, here is what happens:
    1. When Feature “CS3” is selected by the user – the script case “ INSTALLSTATE_LOCAL” is activated.
    2. When Feature “CS3” is not selected by the user – the script case “ INSTALLSTATE_UNKNOWN ” is activated.

     

  3. If you create a InstallScript Custom Action, referencing the InstallScript function – and set the Custom Action’s In-Script execution as “Deferred”, and run the CA in the Execute Sequence – just before the files are installed, here is what happens – essentially :
    1. When Feature “CS3” is selected by the user – the script case “ INSTALLSTATE_ UNKNOWN
      is activated.
    2. When Feature “CS3” is not selected by the user – the script case “ INSTALLSTATE_UNKNOWN ” is activated.

    Note: This scripting won’t work at all if the Custom Action is deferred – you will need to capture the status and preserve it for retrieval later for a Deferred Custom Action.

  4. If you create a InstallScript Custom Action, referencing the InstallScript function – and set the Custom Action’s In-Script execution as “Immediate”, and run the CA in the Execute Sequence – just before the files are installed. Now suppose you use the Add/Remove Control Panel, specify MODIFY and uninstall feature CS3, – here is what happens:
    1. Feature “CS3” – the script case “ INSTALLSTATE_ABSENT “ is activated.

 

So we have a working solution, we can utilize! I know the value from a selected feature is INSTALLSTATE_LOCAL” – so that is good enough to make my scripting easier!

 

There is another method you can check – you can retrieve the MSI Property “ADDLOCAL” for a comma separated list of selected features, such as ADDLOCAL=”ClientServer,CS1,CS2,Server,S1″. This somewhat tricky to capture – its only available after the Standard Action “InstallValidate”, and you can only capture it within the UI Sequence – it’s not available at all during the Execute Sequence. So, essentially you won’t be able to gather this information until after the dialogs have completed – so the script MsiGetFeatureState is a better solution.

 

 

 

 

Advertisements

4 Comments »

  1. I’ve done this using a data driven custom table. Basically you create a table that looks a little bit like LaunchConditions only with an Order column

    Order Condition Message

    This allows you to write any kind of conditional expression you want to be validated. If the expression evaluates to false you display a message ( or log it ) and block the install.

    This allows you to easily author things like mutually exclusive features, at least one feature required, feature only available if a prereq is detected, feature only available on a certain OS and so on.

    You can even detect multiple problems and control the order in which they are displayed.

    Comment by Christopher Painter — January 25, 2011 @ 6:57 pm

    • Chris,
      Have you created a blog about this? I would be interested in learning more of the technique?

      Charles

      Comment by shieldmaster — February 6, 2011 @ 1:46 pm

  2. Great post.
    I used your technique to display custom dialogs for specific features.

    cheers,
    Dan Snitzer

    Comment by Dan Snitzer — February 6, 2011 @ 9:29 am

  3. wow … we are just beginning to realize how much of a pain this is going to be. Why can’t they make the numerical value of each feature available easily after user clicks next? geeze .. really odd that if we click next, back, and then next again … we get the values. Unfortunately we need those values to flush out the 1st time “next” is clicked. -smh- really?

    Comment by jdat747 — September 13, 2013 @ 3:06 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: