16

MyApp version 1.0 contained the file foo.dll. The version of this file was version 10.5.567. Now MyApp is version 2.0 and the version of foo.dll is 2.0.123. The version is LOWER than the old version. The vendor who wrote this dll decided to go backwards with the file version number. This is not a decision I can change.

How do I get WiX to always install this file?

The RemoveExistingProducts action is scheduled after the InstallFinalize action and also cannot be changed.

InstallShield had an 'always overwrite' flag but I don't think I can mimic this without changing the behavior of all files via a compiler switch. I do not want this. I just want to update THIS ONE file.

I have also tried

<RemoveFile Id="foo.dll" On="install" Name="foo.dll" />

But this did not work either. I end up getting 'Error 2753 The file foo.dll is not marked for installation' later.

Mike
  • 263
  • 1
  • 2
  • 8

5 Answers5

12

It is really crazy this post is 10 years old and we also have this problem. The other approaches did not work for us.

How to solve it:

  1. All files which should be copied regardless of their version, must be in their own component
  2. Component element must have a unique Guid, not a *
  3. Set KeyPath to no in the inner File element

Example:

<Component Id="cmpExample" Guid="{5ABE7229-C247-4CBA-B8DE-2C4968CD103E}" >
     <File Id="fileExample" KeyPath="no" Source="$(var.TargetDir)\SomeExample.dll" />
</Component>

I would recommend to aggregate all those component elements in a component group. And furthermore you can use XML Transformation to get rid of those files if you use heat.exe to harvest all your files.

With this solution you can copy the file, even if the installed file version is higher. And it still works as expected when a higher file version will be installed with your upgrade.

avl_sweden
  • 613
  • 4
  • 14
ringwaldK
  • 121
  • 1
  • 6
  • I tried this, following the suggestion in XML Transformation. I was able to set KeyPath to 'no' for several components when building the base installer. But I got errors when building the patch installer, because it used '*' in place of the guid. Do the files need to be marked with KeyPath='no' in both base & patch? If so, when harvesting the files for the patch, can I also use the -gg option on the heat command? – Todd Hoatson Jun 05 '20 at 21:08
  • 1
    OK, I see I cannot use -gg on the heat command when generating a patch, because that would violate your point #2. Also, when I tried with KeyPath='no' on the base, but with KeyPath='yes' on the patch, it didn't work. So it seems that we cannot "install a file regardless of version number" in a WiX patch... only in a base installer. – Todd Hoatson Jun 08 '20 at 18:42
6

This isn't easy because it is against the standard behaviour of MSI-packages. When compiling, you have to set supress-file-options with -sf in light.exe. Then there are no file-informations from your files read. You can set DefaultVersion this version will be used. I have also used RemoveFile in a solution, but i can say that it works. I have add it in same componente where i add the file.

   <Component>
        <File DiskId="1" Id="fooDLL" Name="foo.dll" Vital="yes" 
         DefaultVersion="$(var.MAJORVERSION).$(var.MINORVERSION).$(var.BUILDVERSION)" 
         DefaultLanguage="0"></File>
        <RemoveFile Id='RemoveOldDLL' On='install' Name='foo.dll'/>
   </Componente>

This is not a clean way, but to remove an old version it works for me.

martin
  • 2,957
  • 3
  • 25
  • 46
  • Havent tried this, but looks possible. See my reply in this thread for a link to a list of different approaches. – Stein Åsmul May 25 '11 at 15:12
  • 1
    I tried using DefaultVersion to install a .MDE file and it worked fine when I installed the patch, the file was overwritten correctly. The only problem was the patch wouldn't uninstall. The install log said "New file versioned - existing file unversioned", and the uninstall called for the original media. I still haven't solved this so any suggestions would be welcome. – Dave Dec 11 '15 at 11:39
1

I answered a similar question a while back: Forcing an upgrade of a file that is modified during its initial installation

I think I would use a companion file to solve this problem, but you might get validation errors since the file in question is a dll and hence considered an executable. I believe it would still work, and reliably so.

Community
  • 1
  • 1
Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
0

Annotation

Force always overwrite in Light.exe output with the "InstallShield trick":

XPath="/wixOutput/table[@name='File']/row/field[5]" InnerText=„65535.0.0.0“

  • 1
    I think this is the same as setting `DefaultVersion="65535.0.0.0"` on the `` element. But I'm sure this also has it's own limitations. – Rami A. Dec 14 '18 at 05:23
-1

One thing that could be worth trying is to set RemoveExistingProducts real early in the sequence. The MSI should then remove the old program first, then install the upgrade. This will solve your issue. e.g.

<InstallExecuteSequence>
    <RemoveExistingProducts After="CostFinalize" />
</InstallExecuteSequence>
Christopher B. Adkins
  • 3,499
  • 2
  • 26
  • 29
  • Sadly, it has to happen *before* CostFinalize (because CostFinalize is the step where MSI evaluates which files to update) -- and as far as I can tell, RemoveExistingProducts is not allowed to be sequenced that early. If you find a way around it, I'd love to hear about it though. :) – jalf May 23 '14 at 11:05