How to Explicitly Remove dll During Majorupgrade U

2020-02-15 03:16发布

问题:

We are trying to deploy an update to our product which contains an updated dll. This dll also has a version number so normally the installer should be able to see this and replace the old dll.

Windows installer only cares about the first three numbers when checking version number. However in this case the updated version number looks the same save for the fourth number. So for example if the previous one hade 1.0.0.12 this has 1.0.0.20 hence the installer see them as the same version and does not replace the file. I have no control over the version numbering in this case and since we include a lot of dlls this could happen again in the future.

How would one go about making the installer replace the file no matter if the version number is the same?

After searching for different solutions I have tried to tell the installer to remove the file during the install process. I do not want to remove all files if not necessary. So far I have tried the solution as showed in the included code snippet. The removefile element is new in this version of the installer.

<Component Id="SomeComponent" Win64="yes" Guid="*">
<File Id="SomeFile" KeyPath="yes" Source="$(var.app.TargetDir)\some.dll" />
<RemoveFile Id="RemoveSomeFile" Name="some.dll" On="install"/>
</Component>

The result i expect is for the old dll to be replaced by the new dll however after install the old dll is still there and no new one.

回答1:

Companion Files: How to use Companion Files in WiX - just a snippet (after debugging it was discovered that OP had an issue of needing to downgrade files instead of a problem with number of version digits - very common issue):

<..>

<Component Id="MyFile.exe" Feature="Main">
  <File Id="MyFile.exe" Source="MyFile.exe"></File>
</Component>

<Component Id="MyFile_2.exe" Guid="{0EBDFD64-017B-428F-BB67-3D82EA2A99AF}" Feature="Main">
  <File Source="MyFile_2.exe" CompanionFile="MyFile.exe"></File>
</Component>

<..>

One-Line Summary: In the second component we point to the first component's file so that MyFile_2.exe will install whenever MyFile.exe is installed - regardless of versioning issues.


Older answer below left in for reference and the WiX source that can be used for testing.


MSI Version: Windows installer only cares about the first three numbers when checking version number.

File Version vs ProductVersion: The above statement is generally correct, but to the best of my knowledge (and based on a quick smoke test), this 3-digit restriction only applies to the MSI's ProductVersion (the version of the MSI itself), and not to actual file version numbers.

File versions are respected in 4 digits, as opposed to the 3 digit limit for the MSI's ProductVersion (the version for the MSI itself). Please run a test yourself to be sure. Sample WiX markup to do so below.


REINSTALLMODE: The file-overwrite modifier mechanism REINSTALLMODE can be used to force overwrite files regardless of version. This mechanism must not be used since it can cause a number of problems: unnecessary reboot prompts, downgrading of system shared files, cause some files to be upgraded and others not (old and new packages installed out of sequence), in earlier versions of Windows crashes as protected files are attempted downgraded, etc...


WiX Mockup Test Source: I'll dump a simple test WiX source here to help you test this quickly (on different OS versions for example, I tested on Windows 10):

Incidentally, due to some inherent design characteristics of this sample, it will also illustrate that major upgrades fail when you only bump up the last digit of the 4-digit version number, but file overwrites will work. When you install version 2, you will find two product entries in Add / Remove Programs. This is expected based on the design of the sample. Just uninstall both.

<?define MyVersion = "1.0.0.0" ?>
<?define MyReleasePath = "$(sys.SOURCEFILEDIR)_Files\$(var.MyVersion)\" ?>

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

  <Product Id="*" Name="FileVersioning" Language="1033" Version="$(var.MyVersion)"
           Manufacturer="FileVersioning" UpgradeCode="{4864AA4A-EA1D-4367-8427-85D296B0A2A6}">

    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />

    <MediaTemplate EmbedCab="yes" />
    <Feature Id="Main" Title="FileVersioning" Level="1" />

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLFOLDER" Name="FileVersioning">
          <Component Feature="Main">
            <File Source="$(var.MyReleasePath)MyTestFile.exe"></File>
          </Component>
        </Directory>
      </Directory>
    </Directory>
  </Product>

</Wix>

Usage:

  1. Create WiX project, replace template content with above markup.
  2. Make a sub-folder in WiX project folder called _Files and two further sub folders under there with two versions of the same file as illustrated below.
    • Quick Way: In Visual Studio, right click the WiX project and select Open Folder in File Explorer to get to the WiX project folder quickly.
    • Now paste in two folders or create them.
    • You can open the EXE in Visual Studio to "hack" the version number so you use the same EXE or DLL in both folders with different version numbers. See section below for information.
  3. Change MyVersion define to the version number you want to build. For example: <?define MyVersion = "23.4.5.2" ?>. This also affects where the sample expects the source file to be located on disk.
  4. Update the file name in the File element to match the name of your versioned file (<File Source="$(var.MyReleasePath)MyTestFile.exe"></File>).
  5. Compile setup, install it, inspect version number for installed file.
  6. Change the WiX version and compile the next setup (<?define MyVersion = "23.4.5.3" ?>).
  7. Install on top of existing install. Check that the new version of the file has been installed.

Folder structure for versioned files (create inside main project folder):

_Files
   23.4.5.2\MyTestFile.exe
   23.4.5.3\MyTestFile.exe

Open EXE as Resource: In Visual Studio try this:

  1. File => Open => File
  2. Browse for a versioned file (EXE, DLL, etc...)
  3. Click versioned file once (and only once)
  4. Click the down arrow for the Open button => Open With...
  5. Select Resource Editor and open file.
  6. Locate Version section, open and double click entry.
  7. Change version numbers, save new file version (not on top of existing).

Links:

  • WIX (remove all previous versions)
  • Forcing an upgrade of a file that is modified during its initial installation