Property does not exist or empty when accessed from deferred custom action


Problem


Property is created, but when deferred custom action tries to get its value – property either does not exist or its value is empty.



Sample


Let’s test it with immediate custom action first to make sure that property has a value:


<?xml version=1.0 encoding=UTF-8?>


<Wix xmlns=http://schemas.microsoft.com/wix/2003/01/wi>


 


  <Product Id={94A35E02-D48F-48F1-AC1A-23F62489BBF4}


           Name=Minimal Windows Installer Sample


           Language=1033


           Codepage=1252


           Version=1.0.0


           Manufacturer=Acme Corporation


           UpgradeCode={74069BA4-1D1C-4252-A074-B2EC0C746403}>


 


    <Package Id={4C159FD5-135E-42DE-B36E-22DDDCBA3DCF}


             Description=Minimal Windows Installer Sample


             Comments=This installer database contains the logic and data required to install [ProductName].


             InstallerVersion=200


             Languages=1033


             SummaryCodepage=1252


             Platforms=Intel


             ReadOnly=no


             Compressed=yes


             AdminImage=no


             Keywords=Installer


             ShortNames =no


             Manufacturer=Acme Corporation />


 


    <Media Id=1 Cabinet=CAB001.cab EmbedCab=yes />


 


    <Directory Id=TARGETDIR Name=SourceDir>


      <Directory Id=ProgramFilesFolder>


        <Directory Id=INSTALLDIR Name=Minimal LongName=MinimalInstallation>


 


          <Component Id=Component1


                     Guid={A77C5B06-132D-4884-8E17-EA10A83C812D}>


            <File Id=ReadMe DiskId=1 Name=Readme.txt Source=Readme.txt Vital=yes KeyPath=yes />


          </Component>


 


        </Directory>


      </Directory>


    </Directory>


 


    <Property Id=TESTPROPERTY Value=Hello />


 


    <CustomAction Id=ShowProperty Script=vbscript Execute=deferred>


      <![CDATA[


      MsgBox Session.Property(“TESTPROPERTY”)


      ]]>


    </CustomAction>


 


    <InstallExecuteSequence>


      <Custom Action=ShowProperty Before=InstallFinalize>Not Installed</Custom>


    </InstallExecuteSequence>


 


    <Feature Id=Feature1


             Title=Feature1 title


             Description=Feature1 description


             Level=1


             ConfigurableDirectory=INSTALLDIR >


      <ComponentRef Id=Component1 />


    </Feature>


 


  </Product>


</Wix>



As you can see I explicitly set the value of the TESTPROPERTY property.  Custom Action Type 38 shows the message box with the value of this property.  Build MSI and test it.


Now, let’s make our custom action ShowProperty deferred:


    <CustomAction Id=ShowProperty Script=vbscript


                  Execute=deferred>


      <![CDATA[


      MsgBox Session.Property(“TESTPROPERTY”)


      ]]>


    </CustomAction>



Let’s test it again.  As you can see, the message box is empty.



Why?


As you can see in this article on MSDN, deferred custom action can access only three property:



Also, this article is saying that we need to add custom action to set the property with the same name as deferred custom action to the value of property we want to use in the deferred custom action.  Defereed custom action must access CustomActionData property.  Here is updated version:


    <Property Id=TESTPROPERTY Value=Hello />


 


    <CustomAction Id=ShowProperty Script=vbscript Execute=deferred>


      <![CDATA[


      MsgBox Session.Property(“CustomActionData”)


      ]]>


    </CustomAction>


 


    <CustomAction Id=SetPropertyForShowProperty


                  Property=ShowProperty Value=[TESTPROPERTY] />


 


    <InstallExecuteSequence>


      <Custom Action=SetPropertyForShowProperty Before=InstallInitialize>Not Installed</Custom>


      <Custom Action=ShowProperty Before=InstallFinalize>Not Installed</Custom>


    </InstallExecuteSequence>



I’ve added new immediate Custom Action Type 51 to set the property with the name ShowProperty (same name as deferred custom action) and scheduled it in the InstallExecuteSequence table just before InstallInitialize standard action.  Custom Action ShowProperty is using CustomActionData property now.


Build the MSI and make sure that it is working now.



What if I need more than one property?


If we need to access more than one property, we must pack them into CustomActionData.  For example, if we know for sure that our properties will not have semi-colon in their value, we can concatenate property values and separate values using semi-colon.  Here is an example:


    <Property Id=TESTPROPERTY Value=Hello />


    <Property Id=TESTPROPERTY2 Value=World />


 


    <CustomAction Id=ShowProperty Script=vbscript Execute=deferred>


      <![CDATA[


      Dim properties


      properties = Split(Session.Property(“CustomActionData”), “;”, -1, 1)


      MsgBox properties(0) & “, ” & properties(1) & “!”


      ]]>


    </CustomAction>


 


    <CustomAction Id=SetPropertyForShowProperty


                  Property=ShowProperty


                  Value=[TESTPROPERTY];[TESTPROPERTY2] />


 


    <InstallExecuteSequence>


      <Custom Action=SetPropertyForShowProperty Before=InstallInitialize>Not Installed</Custom>


      <Custom Action=ShowProperty Before=InstallFinalize>Not Installed</Custom>


    </InstallExecuteSequence>



 

Comments (5)

  1. Rakib Hasan says:

    Thanks a lot for this article. You are great.

    Regards

    Rakib Hasan

  2. SamDesilva says:

    while installation of msi i was watching at process explorer ..i see multiple msiexec.exe are runing when i see properties i see like this

    C:WINDOWSsystem32MsiExec.exe -Embedding 59465E02FC8CDF15571B52DDDD811C42

    i come to know this is for deffered custom action and i got the template like this..

    msiexec.exe -Embedding <GUID> – this is the custom action server (indicated by the -Embedding switch)

    here i have doubt what is <GUID> weatehr it stand for component ,Product or what its is…??

  3. Alex Shevchuk says:

    I don’t know what this GUID is. It might be something which is meaningful to this particular run of the installer and during next run this GUID for the same custom action could be completely different.

  4. Nag'a' says:

    What if I want to set a property value from a deferred custom action

  5. Swapnil Sankla says:

    Hi nice article, how to change value of property using custom action data ?

    Please reply to swapprakash@yahoo.co.in if you have solution for this.

    Thanks in advance.