JosephV
Level 2

Mutually exclusive feature install not working as expected

Jump to solution

Good Day All,

Created a Basic MSI

Followed similar suggested path as

https://community.flexera.com/t5/InstallShield-Forum/Mutually-exclusive-feature-install/m-p/61442

However, I cannot get the behavior to do what I want, which is slightly different than the other poster.

I have a Custom dialog created with 4 Radio Buttons, the intention is have the user select one of the four features they want to setup and then only that feature is visible in the Custom Setup dialog that is displayed when Next > is clicked on my Custom Dialog selection page.  I also want that selected feature to be 'enabled' so its selected to install.

This is what I did:

1. Created a custom dialog 'SelectSetupFeature' with Radio Button Group with its Property = SETUPOPTION

2. Added 4 Radio Button's which become "SETUPOPTION1" to "SETUPOPTION4" and each get their 'Value' Property set to A, B, C or D respectively.

3. Defined the 'SelectSetupFeature' Dialog's Next PushButton events as follows:

SelectSetupFeature Next PushButton events.jpg

The intention is that the Next > button is disabled unless they select A B C or D and that works as expected.

The NewDialog is calling CustomSetup and the SETUPOPTION is getting set to A B C or D depending on which radio button selected.

4. In the 'ORGANIZATION > FEATURES' section I have 4 features defined

Seems no matter what combination of feature property settings I use I cannot achieve the result I want.

I only want to see the single feature the user selected via the radio button Dialog, in my Custom Setup dialog It seems that the SETUPOPTION is getting set to the A B C D value but my 'Conditions' for the feature definitions are not working like I expected, Ive tried so many combinations I am unable to get the behavior to work properly.

During runtime it either defaults to "Feature A" or wont show any features at all in the Custom Setup dialog.

(I have the dialog temporarily displaying the INSTALLLEVEL and SETUPOPTION values in right corner)

CustomSetup - SETUPOPTION is A but nothing displays.jpg

In the features definition properties I have tried a variety of combination of things

FeatureA Feature Setup.jpg

Tried setting the Install Level to 0 so it hides it by default, then wanted to use 'Conditions' to set the Install Level to 100 but the feature doesn't seem to show up.

Note: for all four features I have them setup the same basically as above

Any ideas on what I should be doing ?  Perhaps what I want to achieve is not possible with a Basic MSI kit?

Joe

Labels (1)
0 Kudos
1 Solution


I can offer you the following solution:
Your features NewFeature1 (A) and NewFeature1 (B) are without any level-condition (!)
Both of them are visible and have installLevel=150 (!)

RadioGroup Property SELECTFEATURE = 0
RadioA = A
RadioB = B

you have ISScript - Functions

/////////////////////////////////////////////////////////////
// Put this CA after NEXT of Radio-Dialog
function SetFeatureCondition(hMSI)
NUMBER nBuffer;
STRING svProp;
begin

nBuffer=255;
MsiGetProperty(hMSI,"SELECTFEATURE",svProp,nBuffer);

if(svProp=="A") then
SetFeatureStrCondition(hMSI,"NewFeature1",SW_SHOW);
SetFeatureStrCondition(hMSI,"NewFeature2",SW_HIDE);
endif;

if(svProp=="B") then
SetFeatureStrCondition(hMSI,"NewFeature2",SW_SHOW);
SetFeatureStrCondition(hMSI,"NewFeature1",SW_HIDE);
else
endif;
end;

/////////////////////////////////////////////////////////////


function SetFeatureStrCondition(hMSI,szFeature,nShowHide)
NUMBER hDB;
NUMBER hView, hRecord;
NUMBER nResult, nBuffer;
NUMBER nVisible;
STRING szName;
begin

hDB=MsiGetActiveDatabase(hMSI);

// open view table

MsiDatabaseOpenView(hDB, "SELECT * FROM Feature WHERE Feature='"+szFeature+"'", hView);
MsiViewExecute(hView, NULL);

MsiViewFetch(hView, hRecord);
nBuffer = 255;
MsiRecordGetString (hRecord, 1, szName, nBuffer);
nVisible = MsiRecordGetInteger(hRecord, 5);
//MessageBox("Operating on feature: " + szName, INFORMATION);

// löschen
nResult = MsiViewModify(hView, 6, hRecord);

if(nShowHide==SW_HIDE) then
// Set to to HIDDEN
nResult=MsiRecordSetInteger(hRecord, 5, 0);
// Set LEVEL to 150
nResult=MsiRecordSetInteger(hRecord, 6, 150);
else
// Set to to SHOW
nResult=MsiRecordSetInteger(hRecord, 5, 2);//8);
// Set LEVEL to 1
nResult=MsiRecordSetInteger(hRecord, 6, 1);
// Set Attributes to 0
//nResult=MsiRecordSetInteger(hRecord, 8, 1);
endif;

// can only temporarily modify running .msi database
nResult = MsiViewModify(hView, MSIMODIFY_INSERT_TEMPORARY, hRecord);

MsiCloseHandle(hRecord);
MsiViewClose(hView);
MsiCloseHandle(hDB);
end;

 

 

 

 

View solution in original post

3 Replies
roman2
Level 7

Hi JosephV,

The conditional setting of installation level of a feature ends after UserInterface\CostFinalize

You can proof it calling your test setup

setup.exe /V"SETUPOPTION=A"

This way you can see feature "A" in feature dialog.

 

0 Kudos


I can offer you the following solution:
Your features NewFeature1 (A) and NewFeature1 (B) are without any level-condition (!)
Both of them are visible and have installLevel=150 (!)

RadioGroup Property SELECTFEATURE = 0
RadioA = A
RadioB = B

you have ISScript - Functions

/////////////////////////////////////////////////////////////
// Put this CA after NEXT of Radio-Dialog
function SetFeatureCondition(hMSI)
NUMBER nBuffer;
STRING svProp;
begin

nBuffer=255;
MsiGetProperty(hMSI,"SELECTFEATURE",svProp,nBuffer);

if(svProp=="A") then
SetFeatureStrCondition(hMSI,"NewFeature1",SW_SHOW);
SetFeatureStrCondition(hMSI,"NewFeature2",SW_HIDE);
endif;

if(svProp=="B") then
SetFeatureStrCondition(hMSI,"NewFeature2",SW_SHOW);
SetFeatureStrCondition(hMSI,"NewFeature1",SW_HIDE);
else
endif;
end;

/////////////////////////////////////////////////////////////


function SetFeatureStrCondition(hMSI,szFeature,nShowHide)
NUMBER hDB;
NUMBER hView, hRecord;
NUMBER nResult, nBuffer;
NUMBER nVisible;
STRING szName;
begin

hDB=MsiGetActiveDatabase(hMSI);

// open view table

MsiDatabaseOpenView(hDB, "SELECT * FROM Feature WHERE Feature='"+szFeature+"'", hView);
MsiViewExecute(hView, NULL);

MsiViewFetch(hView, hRecord);
nBuffer = 255;
MsiRecordGetString (hRecord, 1, szName, nBuffer);
nVisible = MsiRecordGetInteger(hRecord, 5);
//MessageBox("Operating on feature: " + szName, INFORMATION);

// löschen
nResult = MsiViewModify(hView, 6, hRecord);

if(nShowHide==SW_HIDE) then
// Set to to HIDDEN
nResult=MsiRecordSetInteger(hRecord, 5, 0);
// Set LEVEL to 150
nResult=MsiRecordSetInteger(hRecord, 6, 150);
else
// Set to to SHOW
nResult=MsiRecordSetInteger(hRecord, 5, 2);//8);
// Set LEVEL to 1
nResult=MsiRecordSetInteger(hRecord, 6, 1);
// Set Attributes to 0
//nResult=MsiRecordSetInteger(hRecord, 8, 1);
endif;

// can only temporarily modify running .msi database
nResult = MsiViewModify(hView, MSIMODIFY_INSERT_TEMPORARY, hRecord);

MsiCloseHandle(hRecord);
MsiViewClose(hView);
MsiCloseHandle(hDB);
end;

 

 

 

 

Thank you so much, a few tweaks and it works great,

Just for others, to translate a bit of the solution, in the setup.rul make sure you define your function prototype's

export prototype SetFeatureCondition(HWND);
prototype SetFeatureStrCondition(HWND,STRING,NUMBER);

Otherwise the response from roman2 was bang on.

Much appreciated.

0 Kudos