Joshr
Posts: 33
Joined: Mon Dec 14, 2015 5:40 pm

Public properties and InstallExecuteSequence

Fri Jan 29, 2021 8:35 am

Hello,

I don't understand when a public property is transferred from InstallUISequence to InstallExecuteSequence, and when it is not. I am currently having an issue where a property that, as far as I can tell, should be transferred is not being transferred:

1) I have a dialog event which calls a custom action. This custom action sets the public property INSTALL_DSN to some value.
2) I have an immediate custom action scheduled in InstallExecuteSequence. The data passed to the the custom action (CustomActionData) is "[INSTALL_DSN];File=C:\some\path.txt"
3) When the custom action is invoked, it only receives the string ";File=C:\some\path.txt". The value of INSTALL_DSN is not prepended as expected.

Reviewing the log, I see the INSTALL_DSN is set propertly during the InstallUISequence. However, when Windows Installer spawns the new msiexec.exe, INSTALL_DSN is not one of the (seemingly random) properties Windows Installer passes along.

Everything I can find states that if I want a property to be transferred to InstallExecuteSequence, it only needs to be public (all upper case). But that's not the behavior I'm seeing:
  • Some PUBLIC properties defined in the Property table (also Install Parameters) are transferred, some are not.
  • Some PUBLIC properties tied to User Controls are transferred, some are not.
  • None of the transferred PUBLIC properties are listed in SecureCustomProperties.
I can't find any explanation anywhere that states what properties are transferred from InstallUISequence to InstallExecuteSequence other than "the property needs to be public". Sometimes someone mentions SecureCustomProperties, but Windows Installer is transferring properties not listed here.

How can I get my public property value to transfer to InstallExecuteSequence for an immediate custom action?

Catalin
Posts: 6542
Joined: Wed Jun 13, 2018 7:49 am

Re: Public properties and InstallExecuteSequence

Fri Jan 29, 2021 3:54 pm

Hello Josh,

Indeed, as you have mentioned, all the public properties (all uppercase characters, e.g. MY_PROP) have their value transfered from the InstallUISequence (Wizard Dialogs Stage) to the InstallExecuteSequence (Install Execution Stage)
2) I have an immediate custom action scheduled in InstallExecuteSequence. The data passed to the the custom action (CustomActionData) is "[INSTALL_DSN];File=C:\some\path.txt"
Could you please give me some more details about your custom action type (is it a PowerShell script, a VBScript, etc.)?

Please note that the CustomActionData property is used mostly to pass the property's value to a deferred custom action.

If you want to get the value of your property in your immediate custom action, please refer to our "How to set an installer property using custom actions" article.

For instance, if you have a PowerShell script, you can retrieve the value of your property as it follows:

Code: Select all

$install_dsn = AI_GetMsiProperty INSTALL_DSN
Hope this helps!

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube

Joshr
Posts: 33
Joined: Mon Dec 14, 2015 5:40 pm

Re: Public properties and InstallExecuteSequence

Fri Jan 29, 2021 4:54 pm

Hello, Catalin. Thank you for the reply. My issue is not with reading from the CustomActionData property in my custom action. That all works fine. It's with the value of a public property not being passed in to CustomActionData by Windows Installer.

My first custom action is a function exported from a DLL written in C++. It is executed via dialog event after collecting SQL database connectivity information. The custom action simply generates a DSN string taking into account any property value escaping that needs to occur. The resulting DSN is stored in the property "DB_LOAD_DSN". This custom action is working with no problems. You can see it here in the generated setup.log:

Code: Select all

MSI (c) (EC:74) [06:32:20:436]: PROPERTY CHANGE: Modifying CustomActionData property. Its current value is 'DbExists'. Its new value: 'TARGET=DB_LOAD_DSN;PROPERTIES=DB_SERVER,DB_DATABASE;Provider=MSOLEDBSQL;DataTypeCompatibility=80;Server=DB_SERVER;Database=DB_DATABASE;Integrated Security=SSPI'.
Action ended 6:32:20: AI_DATA_SETTER_32. Return value 1.
MSI (c) (EC:74) [06:32:20:436]: Doing action: SqlServerConnectionDlg
Action start 6:32:20: SqlServerConnectionDlg.
Action ended 6:32:20: SqlServerConnectionDlg. Return value 1.
MSI (c) (EC:74) [06:32:20:436]: Doing action: SqlCreateLoadDsnTrusted
Action start 6:32:20: SqlCreateLoadDsnTrusted.
MSI (c) (EC:84) [06:32:20:436]: Invoking remote custom action. DLL: C:\Users\ADMINI~1\AppData\Local\Temp\2\MSIEF0A.tmp, Entrypoint: IS_MsiExpandDsn
MSI (c) (EC!54) [06:32:20:468]: PROPERTY CHANGE: Adding DB_LOAD_DSN property. Its value is 'Provider=MSOLEDBSQL;DataTypeCompatibility=80;Server=localhost\SQLEXPRESS;Database=Test;Integrated Security=SSPI'.
Action ended 6:32:20: SqlCreateLoadDsnTrusted. Return value 1.
You can see above that the property DB_LOAD_DSN is set to the value "Provider=MSOLEDBSQL;DataTypeCompatibility=80;Server=localhost\SQLEXPRESS;Database=Test;Integrated Security=SSPI"

My second custom action (LoadDatabase_Cost) is also exported from a DLL written in C++. It is executed via the "Call Function from Attached Native DLL". It loads a SQL database from data in a custom file form at we use here at the office. It needs to be passed a SQL connection DSN (the value of DB_LOAD_DSN) and the file from which to load the data. I have it configured as follows:
action.jpg
action.jpg (89.91KiB)Viewed 4167 times
As you can see from the above screenshot, the Action Data is [DB_LOAD_DSN];File=[AI_DBD_FILE]".

The custom action is scheduled as follows:
scheduled.jpg
scheduled.jpg (36.73KiB)Viewed 4167 times
When the install runs, the LoadDatabase_Cost receives the following data. Notice the value of DB_LOAD_DSN is missing (it should be before the semicolon):

Code: Select all

;File=C:\Users\ADMINI~1\AppData\Local\Temp\2\TestProduct\Data.dbd
I have confirmed this is an issue with how Windows Installer is passing the data to my custom action, not the custom action itself. From the log:

Code: Select all

MSI (s) (A4:80) [06:32:36:146]: Doing action: AI_DATA_SETTER_7
Action start 6:32:36: AI_DATA_SETTER_7.
MSI (s) (A4:80) [06:32:36:146]: PROPERTY CHANGE: Modifying CustomActionData property. Its current value is 'C:\'. Its new value: ';File=C:\Users\ADMINI~1\AppData\Local\Temp\2\TestProduct\Data.dbd'.
Action ended 6:32:36: AI_DATA_SETTER_7. Return value 1.
Further, when Windows Installer spawns the new msiexec process, it does not pass the value of DB_LOAD_DSN. From the log:

Code: Select all

MSI (s) (A4:80) [06:32:36:005]: ******* RunEngine:
           ******* Product: C:\Users\Administrator\AppData\Roaming\TestCompany\TestProduct\install\TestInstall.msi
           ******* Action: INSTALL
           ******* CommandLine: **********
...<snip>...
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding APPDIR property. Its value is 'C:\Program Files (x86)\CompanyName\TestProduct'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Modifying DB_HAS_LOGIN property. Its current value is '0'. Its new value: '1'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Modifying DB_BACKUP_FILE_ESCAPED property. Its current value is 'db.bak'. Its new value: ''''.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Modifying DB_SERVER property. Its current value is 'localhost'. Its new value: 'localhost\SQLEXPRESS'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding AI_SETUPEXEPATH property. Its value is 'C:\Users\Administrator\Desktop\TestInstall.exe'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding TARGETDIR property. Its value is 'C:\'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding AI_INSTALL property. Its value is '1'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding AI_SETUPEXEPATH_ORIGINAL property. Its value is 'C:\Users\Administrator\Desktop\TestInstall.exe'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding AI_DBD_FILE property. Its value is 'C:\Users\ADMINI~1\AppData\Local\Temp\2\TestProduct\data.dbd'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding AI_INSTALLSUPPORT_DLL property. Its value is 'C:\Users\ADMINI~1\AppData\Local\Temp\2\TestProduct\InstallSupport.dll'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding USERNAME property. Its value is 'Windows User'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding COMPANYNAME property. Its value is 'Caphyon'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding SOURCEDIR property. Its value is 'C:\Users\Administrator\AppData\Roaming\CompanyName\TestProduct\install\'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding AIEXTERNALUI property. Its value is '5'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding EXECUTEACTION property. Its value is 'INSTALL'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding AI_MORE_CMD_LINE property. Its value is '1'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding ACTION property. Its value is 'INSTALL'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding CLIENTPROCESSID property. Its value is '2492'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding SECONDSEQUENCE property. Its value is '1'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding CHAINERUIPROCESSID property. Its value is '748Chainer'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding CLIENTUILEVEL property. Its value is '0'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding ADDLOCAL property. Its value is 'C04995A3299245EBA2122CEA2FA525AD,A2119716F144C9480694BF36747BC88,CE6A2D55BB654A48ADDB534115E9C322,D5D54AFFAD641D2B30BF3F03FA9D51C,MainFeature'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding PASSWORD_MATCH property. Its value is '1'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding PRIMARYFOLDER property. Its value is 'APPDIR'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding ROOTDRIVE property. Its value is 'C:\'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding AI_PREREQDIRS property. Its value is 'C:\Users\Administrator\AppData\Roaming\CompanyName'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding AI_TEMP_FILE_ROLLBACK_INFO property. Its value is 'C:\USERS\ADMINI~1\APPDATA\LOCAL\TEMP\2\TESTPRODUCT\DATA.DBD|C:\USERS\ADMINI~1\APPDATA\LOCAL\TEMP\2\|C:\USERS\ADMINI~1\APPDATA\LOCAL\TEMP\2\TESTPRODUCT\INSTALLSUPPORT.DLL'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding AITEMPFILESEXTRACTED property. Its value is 'YES'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding AI_FOUND_PREREQS property. Its value is '.NET Framework 4.7.2|Visual C++ Redistributable for Visual Studio 2015-2019 x86|Visual C++ Redistributable for Visual Studio 2015-2019 x64|SQL Server OLE DB Driver 18 x64|MSXML 6.0 Parser SP2 x86|MSXML 6.0 Parser SP2 x64'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding SETUPEXEDIR property. Its value is 'C:\Users\Administrator\Desktop\'.
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding EXE_CMD_LINE property. Its value is '/exenoupdates  /forcecleanup  /wintime 1611785946 /L*V "C:\Users\Administrator\Desktop\Setup.log" '.
MSI (s) (A4:80) [06:32:36:021]: Machine policy value 'DisableAutomaticApplicationShutdown' is 0
MSI (s) (A4:80) [06:32:36:021]: PROPERTY CHANGE: Adding MsiRestartManagerSessionKey property. Its value is 'cb3c6557bf12bd42ab84e551830e8926'.
MSI (s) (A4:80) [06:32:36:021]: RESTART MANAGER: Session opened.
MSI (s) (A4:80) [06:32:36:021]: Engine has iefSecondSequence set to true.
...
I have also noticed that it does not pass a number of public properties that I have set and I cannot find any consistent reason for that.

For example, I have another property DB_RUNTIME_USERNAME that is defined in the property table and associated with a dialog control. This property is NOT passed to InstallExecuteSequence. DB_SERVER, which is configured exactly the same way so far as I can tell, is passed to InstallExecuteSequence.

A second example, DB_BACKUP_FILE_ESCAPED, is set during a custom action during the InstallUISequence, just like DB_LOAD_DSN. However, DB_BACKUP_FILE_ESCAPED is passed to InstallExecuteSequence while DB_LOAD_DSN is not.

I can not figure out Windows Installer's logic, here.

Joshr
Posts: 33
Joined: Mon Dec 14, 2015 5:40 pm

Re: Public properties and InstallExecuteSequence

Fri Jan 29, 2021 5:23 pm

Okay.

Manually modifying the Property table in the "Table Editor" and adding DB_LOAD_DSN to SecureCustomProperties seems to have resolved that issue.

However, other public properties I created are NOT listed in SecureCustomProperties, yet are being transferred.

Why is Windows Installer picking some public properties and not others? Why does a property sometimes need to be added to SecureCustomProperties, and other times not?

Does Advanced Installer have a method of modifying SecureCustomProperties without manually editing it in the Property table? Is this the correct solution to this problem, or is it just masking some other problem?

Catalin
Posts: 6542
Joined: Wed Jun 13, 2018 7:49 am

Re: Public properties and InstallExecuteSequence

Thu Feb 04, 2021 9:02 pm

Hello,

This is really strange, indeed.

Could you please give me some more details about the environment you are installing your setup to?

Is it an usual Windows 7/8.1/10 machine?

I am asking because, after a bit of research, I found out that the SecureCustomProperties property is related to a managed installation (which, to be fully honest with you, is not yet really clear to me what it is).

Based on the "Restricted Public Properties" article:
In the case of a managed installation, the package author may need to limit which public properties are passed to the server side and can be changed by a user that is not a system administrator. Some restrictions are commonly necessary to maintain a secure environment when the installation requires the installer to use elevated privileges.
As you may know, the "server side" is the "Install Execute Sequence", while the "client side" is the "InstallUISequence".

This would make a little bit of sense in your case, as adding your property to the "SecureCustomProperties" property seems to solve the issue.

However, on the other hand, it is really strange that another property that you are setting during the UI stage is passed over, while others are not.
A second example, DB_BACKUP_FILE_ESCAPED, is set during a custom action during the InstallUISequence, just like DB_LOAD_DSN. However, DB_BACKUP_FILE_ESCAPED is passed to InstallExecuteSequence while DB_LOAD_DSN is not.
Is the DB_BACKUP_FILE_ESCAPED property added by default to the "SecureCustomProperties" property (by default = without you manually adding it)?

If this is the case, then it would make sense why it is passed.

If possible, could you please create a sample project which reproduces this issue and forward it to me (either here or by e-mail at support at advancedinstaller dot com) together with a test-case which I can follow, so I can further investigate this and see what I can find?

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube

Return to “Common Problems”