cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
honolua
Level 7

Help with MsiGetProperty in custom InstallScript action?

Project Type: Basic MSI

I've not been able to find how to do this yet. I've got a custom dialog box in the UI sequence. There's an edit control with a property named SPS_DATASOURCE_NAME. When I enter a value in this field it appears to be kept for later retrieval in an InstallScript custom action (immediate execution). However, if I change to deferred execution I seem to be losing my property. My InstallScript code is:

	nDataSourceNameLen = DATA_SOURCE_NAME_LEN + 1;

nResult = MsiGetProperty( hMSI, "SPS_DATASOURCE_NAME", szDataSourceName, nDataSourceNameLen );
MessageBox( "data source name: " + szDataSourceName, INFORMATION );


Why does this work if it is set to immediate execution but not when set to deferred execution?
Labels (1)
0 Kudos

(10) Replies
schmoli
Level 6

Long story short: you have to access CustomActionData in your deferred custom action, normal properties aren't available.

I could go on and on about this, but Christopher Painter has already done this perfectly, so I suggest you read this:

http://blog.deploymentengineering.com/2006/06/installscript-meet-customactiondata.html

...and follow his link to installsite. I use his handy little installscript function every single day, even wrote one in c# for my DTF CA's.
0 Kudos
RobertDickau
Flexera Alumni

There's also the topic "Accessing or Setting Windows Installer Properties Through Deferred, Commit, and Rollback Custom Actions".
0 Kudos
honolua
Level 7

I've read over that link and two others linked from it. I still do not have this working correctly yet. My guess is that my type 51 custom action is not defined properly. I set it up to execute as the final activity before "Execute Action" in the UI sequence. However, I don't think CustomActionData is being set to anything at all. I added a MessageBox to the MsiGetCustomActionDataAttribute to display the full /name=value but the message box was empty. How do I get the /name=value into CustomActionData correctly to make this functionality work (yes, I am new to InstallShield)?
0 Kudos
Christopher_Pai
Level 16

The Type 51 CA should be scheduled in the execute sequence and the name of the property it is setting must match the name of the deferred CA. This is how the join is made. Also be aware of Public Properties ( vs private properties ) and the SecureCustomProperties property.

FYI- If you are using C#/DTF ... it already has a CustomActionData class that makes serializing/deserializing super easy. You don't have to write the kind of code I wrote.

(In fact the comment on my blog was somewhat prophetic as DTF does exactly what I was contemplating doing .. I just didn't have a strong enough business reason to invest in the pattern. )
0 Kudos
Branstar
Level 3

I found this very helpful, thanks 🙂
0 Kudos
honolua
Level 7

I finally got back to this (after a long period on another project) and was able to figure out how to make this work for a single property. How do I get multiple properties set? Everything I've tried seems to trash CustomActionData. What's the trick to sending multiple values into CustomActionData?
0 Kudos
RobertDickau
Flexera Alumni

Each deferred action gets one CustomActionData, so common practice is to pack multiple properties into CustomActionData in immediate mode ([PROP1]|[PROP2]|[PROP3]|etc.), and then unpack them (using StrGetTokens in InstallScript, for example) in the deferred action.
0 Kudos
Christopher_Pai
Level 16

Have you tried googling for "installscript customactiondata"?
The first two hits are a sample that I put together that should be helpful to you.
0 Kudos
honolua
Level 7

RobertDickau wrote:
Each deferred action gets one CustomActionData, so common practice is to pack multiple properties into CustomActionData in immediate mode ([PROP1]|[PROP2]|[PROP3]|etc.), and then unpack them (using StrGetTokens in InstallScript, for example) in the deferred action.


So the basic idea is to create a single Type 51 custom action that pushes multiple values into the CustomActionData which I later decode during a deferred custom action in the execute sequence. I have about 10 or 15 properties I need to pass through to a deferred action in the execute sequence (user name, password, etc. that are used while executing some installed executables). All of these need to be set in a single Type 51 action?

Christopher Painter wrote:
Have you tried googling for "installscript customactiondata"?
The first two hits are a sample that I put together that should be helpful to you.


I've read over both of these several times and have imported the code you wrote. The difficulty for me is not with the decoding of CustomActionData. I understand the script code perfectly well. My difficulty is on the other end of this process, populating CustomActionData in the first place (with multiple properties). Is this done with a single Type 51 custom action or with multiple?
0 Kudos
Christopher_Pai
Level 16

It depends on your needs. If you just have something like:

/SUPPORTDIR=[SUPPORTDIR] /INSTALLDIR=[INSTALLDIR]

Then you could use a type 51.

IF you have something more complicated like data driven custom actions then you might need to query a table, evaluate component action states and create a dataset that tells the deferred which actions to perform, then you'll probably want an InstallScript Ca that does all of this then sets the property.
0 Kudos