0

I have a component

<Component Id="ProductComponent" Guid="7935315f-4242-4c7a-a02c-6fd256805356">
    <CreateFolder/>
      <File
          Id="propFile"
          Name="aaa.properties"
          DiskId="1"
          Source="$(var.Project.TargetDir)"
          Vital="yes"
          KeyPath="yes" ></File>
      <?endif?>

</Component>

I want to copy the file just on install , not upgrade. But I can't find how to do it.

Any idea?

  • Try to generate the file on launch if you can? You can also install a template and use that to create the real file. Downloading a settings file is also possible (proxy / firewall issues possible). – Stein Åsmul May 14 '20 at 11:45
  • What I meant was that generating a file can be done from code alone (internal defaults), from a template file copied and then updated via code or just by copying a template file to a new location from a read-only copy. And various other options. – Stein Åsmul May 14 '20 at 16:58
  • ^^ this. It's best to keep defaults and user settings in their own files as MSI wants to manage the files it installs. – Christopher Painter May 19 '20 at 04:38

2 Answers2

0

Have you tried using Condition element. I think you can provide a Condition inside Component element to check whether product is already installed or not. If not installed, then create file.

<Component Id="ProductComponent" Guid="7935315f-4242-4c7a-a02c-6fd256805356">
  <Condition> NOT Installed </Condition>
  <CreateFolder/>
  <File
       Id="propFile"
       Name="aaa.properties"
       DiskId="1"
       Source="$(var.Project.TargetDir)"
       Vital="yes"
       KeyPath="yes" ></File>
</Component>
HRM
  • 2,097
  • 6
  • 23
  • 37
  • Based on 20 years of MSI experience, I don't see how this would work. This condition would always evaluate to true for first time installs and major upgrades. For repairs and minor upgrades/patches it doesn't get evaluated at all because the component isn't transitive. The initial installation state (which would always be yes) is used. – Christopher Painter May 19 '20 at 04:40
  • @ChristopherPainter, I'm not an expert in Wix. Just saw this question and tried to help the OP. My intention was to give the OP an idea about tag and I added NOT Installed condition because I read that this condition is the one which will evaluate to true only during initial installation which is what OP wants. Refer here - http://msi-faq.wikidot.com/msi-conditions or refer this SO post - https://stackoverflow.com/a/538876/1672927. – HRM May 19 '20 at 09:58
  • The problem is you now have an accepted answer (the OP obviously didn't test the solution) which is incorrect. For why read: https://learn.microsoft.com/en-us/windows/win32/msi/component-table "Note that unless the Transitive bit in the Attributes column is set for a component, the component remains enabled once installed even if the conditional statement in the Condition column later evaluates to False on a subsequent maintenance installation of the product." – Christopher Painter May 20 '20 at 13:03
  • I've added an answer that I've found to help many clients solve this problem with the simplest more reliable approach that I know of. – Christopher Painter May 20 '20 at 13:08
0

This is a weak spot of MSI (which WiX uses).

MSI installs a file User modifies the file MSI goes to install the file. Should it:

a) overwrite and lose user data

b) not overwrite and lose new applciation data

c) merge --- MSI doesn't support this.

If the user data is only one or few attributes there are tricks with custom actions to harvest the user data and reapply it but this is very tricky stuff.

IMO, the best way to approach this is never keep user data in a file installed by the installer. Take app.config appSettings element as an example. It was an atttribute that allows you to extend the file with another file that overrides the settings in the first file. Using this pattern the installer can lay down the app config and the application can create the override file and everything just works because MSI doesn't have to deal with the problem at all.

Christopher Painter
  • 54,556
  • 6
  • 63
  • 100