TemplateFile not reading properties correctly!

Jan 12, 2012 at 3:57 PM

Hi,

I need my MSI to dynamically set some .conf and .properties files at installation time.  I've spent the whole day implementing this with TemplateFile, only to find that it does not work as expected!

It seems to read the values out of the property table directly.  If I change these properties with a custom action before the TemplateFiles custom actions run, it still reads the original value instead of the new value.  I'm therefore unable to use this to set a value in a config file obtained from an input in the UI.  I'm not sure if it was intended for this purpose, but I thought I had it working great until I got to testing all of my output.

A dedicated search and replace text custom action would be sweet to have instead though!

Thanks,

Dan 

Coordinator
Jan 12, 2012 at 9:19 PM

TemplateFile should do what you want it to do. I think you're just missing the embedded <SystemTools:TemplateFileProperty Id="" Name="FOOBAR" Value="[FOOBAR]" /> inside the TemplateFile node. Check out this demo.

Jan 12, 2012 at 10:02 PM

Here's an example snippet.  It plugs the values into the file, but only if they are authored into the Property table and it ignores any values that are set or modified during execution:

<Component Id="postgresql.conf" Guid="*">

<File Id="postgresql.conf" KeyPath="yes" Source="postgresql.conf" />

<SystemTools:TemplateFile Id="postgresql.conf" Source="[#postgresql.conf]" Target="[#postgresql.conf]" ExecuteOnInstall="yes">

<SystemTools:TemplateFileProperty Id="port" Name="port" Value="[PORTPOSTGRESQL]" />

</SystemTools:TemplateFile>

</Component>

 

I sequence a custom action to run early on to set this property to something different than the default.  I can see in the MSI log that this property changes.  When the immediate mode TemplateFile CA runs, I can see XML being stored in the custom action data, which contains the original value of my property, not the value I just updated it to.

I'm using this with WiX 3.6 beta by the way, which is probably not supported.

Coordinator
Jan 12, 2012 at 10:08 PM

Make that property all CAPS to start (I remember that it might behave differently). Does that change anything?

Jan 12, 2012 at 11:19 PM

Do you mean like this?

<SystemTools:TemplateFileProperty Id="PORT" Name="PORT" Value="[PORTPOSTGRESQL]" />

The original .conf file uses lower case and I don't know if it's case sensitive.  Anyway, I've gone for the alternative of running fart.exe from the binary table to search and replace, I will revisit this if time allows - got a deadline to meet!

Coordinator
Jan 12, 2012 at 11:58 PM

Yes. MSI properties are case sensitive. CAPITALIZED properties are public, so I think your lowercase property is not actually set for another CA to pickup. But I am guessing, you should try it.

Jan 13, 2012 at 12:05 AM

I know properties are case sensitive - my property is PORTPOSTGRESQL, which is upper case.  I have a config file with a line in it like this:

port = [PORTPOSTGRESQL]

And my PORTPOSTGRESQL property is set to 5432.  It correctly tweaks the config file, but if I change that property value during installation, it still writes 5432 to the config file.  I don't think capitilising the word PORT would help as it's not an MSI property as such.

Coordinator
Jan 13, 2012 at 12:39 AM

Ok. You're confused. The template file cannot evaluate properties from your MSI because it's a deferred CA (insert long technical explanation here). It gets only properties from the table, which is exactly the problem you're having. So you need to pass these property values to the TemplateFile extension. So if you add <SystemTools:TemplateFileProperty Id="PORT" Name="PORT" Value="[PORTPOSTGRESQL]" /> the property you need to use in the template file is PORT, not PORTPOSTGRESQL.