The accepted answer from Bodgan Mitrache does not seem to be completely valid since it's not possible to run msiexec command from another msi package.
The first part is still correct. You have to fix the problem in the wix project and generate a new package with the same ProductCode/Version and with the MSI database only. We will use this package to recache the previous one so that it will be possible to uninstall it successfully.
In the new installer, you need 2 steps:
- recaching the previous msi
- launch new msi (product update)
The only way I found is to create a Wix bundle to chain sequentially the 2 steps.
1- Recaching operation can be made by a standalone executable consisting in a simple call to msiexec /fv valid_recache.msi. Here is a C++ example:
#include <Windows.h>
int main()
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
SHELLEXECUTEINFO shExecInfo;
shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_UNICODE;
shExecInfo.hwnd = NULL;
shExecInfo.lpVerb = L"open";
shExecInfo.lpFile = L"cmd";
shExecInfo.lpParameters = L"/c msiexec /fv path_to\\recache.msi";
shExecInfo.lpDirectory = NULL;
shExecInfo.nShow = SW_SHOW;
shExecInfo.hInstApp = NULL;
ShellExecuteEx(&shExecInfo);
WaitForSingleObject(shExecInfo.hProcess, INFINITE);
}
2- Create your new msi from your project as usual (with new ProductCode and upper version number)
Combine the 2 steps in a Wix bundle project which can looks like this (useful link here):
<?xml version="1.0" encoding="UTF-8"?>
<Wix
xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle
Name="your_name"
Version="1.0.0"
Manufacturer="your_organization"
UpgradeCode="your_uuid"
Copyright="your_copyright"
AboutUrl="your_url">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.HyperlinkLargeLicense">
<bal:WixStandardBootstrapperApplication
LicenseUrl=""
LogoFile="your_logo"
ShowVersion="yes"
SuppressOptionsUI="yes"/>
</BootstrapperApplicationRef>
<!--Do registry search to find the current msi package version-->
<util:RegistrySearch
Root="HKLM"
Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{ProductCode}"
Value="Version"
Variable="CurrentMsiPackageVersion"
Result="value"
Win64="yes" />
<Chain>
<!--Do recaching only if the current version is the invalid one-->
<ExePackage
Id="Patch"
SourceFile="MsiRecache.exe"
Vital="yes"
InstallCondition="(CurrentMsiPackageVersion="invalid_msi_version")">
<Payload Name="recache.msi" SourceFile="relative_path_to\recache.msi"/>
</ExePackage>
<!--Launch new installation-->
<MsiPackage
Id="your_id"
SourceFile="your_setup.msi"
DisplayInternalUI="yes"
Vital="yes"/>
</Chain>
</Bundle>
</Wix>
Last, generate the bundle by calling:
candle.exe -ext WixBalExtension -ext WixUtilExtension bundle.wxs
light.exe -ext WixBalExtension -ext WixUtilExtension bundle.wixobj
Note that the bundle will have .exe extension instead of msi.