1

Background

WiX & the Windows Installer are completely new to me.

In production, we used an MSI (created using WiX) to install our software. The MSI references a third-party assembly (e.g. OtherCompany.ThirdParty.dll, version 2.5).

The next release of our software must reference an older version of the third-party assembly (e.g. OtherCompany.ThirdParty.dll, version 1.7).

While I understand that installing an older version of a dependency is uncommon, it must happen.

So my question is... how do you configure a MSI (generated by WiX) to use an older version of an assembly without having to completely uninstall the existing package?

Options

We have explored the following:

  1. Increment the assembly's version
    • it's a third party assembly, and
    • for traceability this is not an option
  2. rename the assembly
    • the dependency is being retrieved using NuGet... so this won't be straight forward
  3. force existing install to be completely removed (automatically or manually)
    • we don't want configuration information that was collected during the previous installation to be lost, so this isn't an option
  4. schedule RemoveExistingProducts before costing
    • not recommended by Microsoft (see: MSDN)
  5. custom action: to delete dependency
    • if the installation fails, the application may be left in an undefined state
  6. override file version in setup
    • moving forward, this will be error prone
  7. changing the REINSTALLMODE
    • From the articles that I have read, it appears that this should only be used as a last resort.
  8. use a WIX companion file
    • am still investigating

For Moderators

I am aware that there are other SO posts on this subject. Please note that several of the recommended solutions are incomplete or are error prone.

References

Pressacco
  • 2,815
  • 2
  • 26
  • 45

1 Answers1

3

Some issues are best solved by the application design rather the deployment.

There are two places to save a particular version of a .NET assembly: the GAC or the application folder (or subfolder with probing privatePath). In either case, you might want to use a bindingRedirect.

Also, you can load from a specific location using AppDomain.AssemblyResolve, provided the binding is not successful using the GAC.

General Reference: How the Runtime Locates Assemblies—thanks to @Pressacco.

Tom Blodget
  • 20,260
  • 3
  • 39
  • 72
  • 1
    Thank you Tom. The final solution: <1> removed the `OtherCompany.ThirdParty.dll` (version 2.5) from the installer, <2> added `OtherCompany.ThirdParty.dll` (version 1.7) to the installer so that the DLL is installed to a new directory, and <3> took advantage of [probing](https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/probing-element) to load the assembly from the new path. **Note** to other developers who are going to implement this... assembly loading behaves differently for signed vs unsigned assemblies. See MSDN: How the Runtime Locates Assemblies – Pressacco Oct 26 '17 at 12:57