title: How to avoid having two versions of a product installed with Windows Installer / MSI?
body: <p>I have written and am maintaining a number of Wix installation source files which I use to build MSI files for distribution of my application.</p>
  
  <p>I have not explicitly programmed for any kind of upgrading, updating, reinstallation or anything of the kind -- there is a single feature that consists of a number of components with stable GUIDs and I have observed that at least a clean installation does what I expect it to.</p>
  
  <p>However, I (and anyone in possession of the MSI files I distribute) may seemingly install distinct versions of my application side-by-side using their respective (distinct) MSI files. Which isn't a problem in itself, except that I obviously use the same folder as installation target -- "%ProgramFiles(x86)%\Foobar" -- to install the application (version regardless) in. Meaning that in effect there is always ever one version that ends up being installed.</p>
  
  <p>I would argue that Windows Installer behaves correctly in so far that it updates files from whichever MSI package it installed last. One interesting side-effect of this is that if the last MSI was of earlier version, the files in the application folders would be overwritten with the copies from that earlier version.</p>
  
  <p>But none of that seems to be the actual problem to me. I want to fix the disparity between what is actually installed (a single application version) and what Windows tracks as installed -- in my case two records of two distinct application versions.</p>
  
  <p>Since I install the application in a folder that doesn't depend on the version being installed, tracking multiple application versions by Windows is a mistake.</p>
  
  <p>So I guess my question is, how do I fix this so that only one version is shown (reflecting reality) or what's the idiomatic approach in these kind of cases? I deliberately did not overspecify my Wix source code, hoping in return that Windows Installer would use some built-in intelligence to figure everything out on its own. But I may need to add some explicit upgrade or uninstall-previous-version-first instructions, I suppose.</p>
  
  <p>My minified Wix source code (file "foobar.wxs") would look like this:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
  &lt;Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"&gt;
      &lt;Product Name="Foobar" Manufacturer="ACME Inc." Id="*" UpgradeCode="ae9a7d6d-6c2d-446a-97d9-9dbe829d2ea8" Language="1033" Codepage="1252" Version="!(wix.PRODUCT_VERSION)"&gt;
          &lt;Package Id="*" Languages="1033" SummaryCodepage="1252" Compressed="yes" InstallerVersion="200" /&gt;
          &lt;Icon Id="foobar" SourceFile="!(wix.APPPATH)/foobar.ico" /&gt;
          &lt;Property Id="ARPPRODUCTICON" Value="foobar" /&gt;
          &lt;Property Id="ARPCOMMENTS" Value="Gives you full foobar powers" /&gt;
          &lt;MediaTemplate EmbedCab="yes" CompressionLevel="high" /&gt;
          &lt;Directory Id="TARGETDIR" Name="SourceDir"&gt;
              &lt;Directory Id="DesktopFolder" /&gt;
              &lt;Directory Id="ProgramFilesFolder"&gt;
                  &lt;Directory Id="INSTALLDIR" Name="Foobar" FileSource="!(wix.APPPATH)"&gt;
                      &lt;Component&gt;
                          &lt;File Id="foobar.exe" Name="foobar.exe" /&gt;
                      &lt;/Component&gt;
                      &lt;!-- There are other components like above (assets) --&gt;
                  &lt;/Directory&gt;
              &lt;/Directory&gt;
              &lt;Directory Id="ProgramMenuFolder"&gt;
                  &lt;Directory Id="foobar_menu" Name="Foobar"&gt;
                      &lt;Component Id="foobar_shortcut" Guid="e80a6b95-a145-453a-b327-65a977e741fe"&gt;
                          &lt;Shortcut Icon="foobar" Id="foobar_shortcut" Name="Foobar" Target="[foobar]foobar.exe" /&gt;
                          &lt;Shortcut Directory="DesktopFolder" Icon="foobar" Id="foobar_desktop_shortcut" Name="Foobar" Target="[foobar]foobar.exe" /&gt;
                          &lt;RegistryValue KeyPath="yes" Root="HKMU" Key="Software\[Manufacturer]\[ProductName]" Type="string" Value="" /&gt; 
                          &lt;RemoveFolder Id="remove_foobar_menu" On="uninstall" /&gt;
                      &lt;/Component&gt;
                  &lt;/Directory&gt;
              &lt;/Directory&gt;
              &lt;Directory Id="CommonAppDataFolder"&gt;
                  &lt;Directory Id="app_data_foobar" Name="foobar"&gt;
                      &lt;Component Guid="" Id="app_data_config_folder"&gt;
                          &lt;CreateFolder /&gt;
                      &lt;/Component&gt;
                      &lt;Component Guid="" Id="app_data_config_folder_log_file"&gt;
                          &lt;File Name="foobar.log" Source="foobar.log.template"&gt;
                              &lt;!-- Add write access permission to the log file to members of "Users" group. --&gt;
                              &lt;!-- PermissionEx Sddl="D:AR(A;;GWGR;;;BU)" / --&gt;
                              &lt;!-- Bug with Windows Installer, can't use PermissionEx/MsiLockPermissionsEx table. See https://stackoverflow.com/questions/55145282/how-to-include-inherited-permissions-when-specifying-permissions-for-a-file-inst --&gt;
                              &lt;util:PermissionEx Append="yes" GenericWrite="yes" User="Users" /&gt;
                          &lt;/File&gt;
                      &lt;/Component&gt;
                  &lt;/Directory&gt;
              &lt;/Directory&gt;
          &lt;/Directory&gt;
          &lt;Feature Id="foobar"&gt;
              &lt;ComponentGroupRef Id="foobar" /&gt;
              &lt;ComponentRef Id="foobar_shortcut" /&gt;
              &lt;ComponentRef Id="app_data_config_folder" /&gt;
              &lt;ComponentRef Id="app_data_config_folder_log_file" /&gt;
          &lt;/Feature&gt;
      &lt;/Product&gt;
  &lt;/Wix&gt;
  </code></pre>
  
  <p>I am compiling the object file with the following Windows Command Prompt line:</p>
  
  <pre><code>candle.exe -ext WixUtilExtension -out %TEMP% foobar.wxs
  </code></pre>
  
  <p>And then generating the MSI file with:</p>
  
  <pre><code>light.exe -ext WixUtilExtension -spdb "-dAPPPATH=%apppath%" "-dPRODUCT_VERSION=%version%" -out %TEMP%\foobar-%version%.msi %TEMP%\foobar.wixobj
  </code></pre>
  
  <p>(using Wix 3.11.1.2318)</p>