My product has a helper executable to uninstall all related sub-products. I uninstall based on upgrade codes of all sub-products.
First, I fetch the product code from upgrade code using MsiEnumRelatedProducts function. Then I try to uninstall the product using MsiConfigureProductEx function.
The problem is MsiConfigureProductEx
is returning error.
Invoked Function: MsiConfigureProductsEx
Return Code: 1605 (0x00000645)
Description: This action is only valid for products that are currently installed.
Why is MsiEnumRelatedProducts
returning a invalid product code ? I searched through the windows registry to see if such product code exists. There isn't any. How to debug the issue ?
Edit: Added minimum code that reproduces issue.
// UpgradeCodes is an array having upgrade codes of all modules.
TCHAR lpProductCode[GUID_STR_LENGTH];
const TCHAR tszNoReboot[] = _T("REMOVE=ALL REBOOT=ReallySuppress DISABLE_REBOOT_PROMPT=1");
for (size_t i = 0; i < sizeof(UpgradeCodes) / sizeof(UpgradeCodes[0]); i++)
{
tstring tstrUpgradeCode = UpgradeCodes[i];
DWORD dwIndex = 0;
size_t status;
// for each of the upgrade code, get all the products
do
{
status = MsiEnumRelatedProducts(UpgradeCodes[i],
0,
dwIndex,
lpProductCode);
if (ERROR_SUCCESS == status)
{
UINT uiReturn = MsiConfigureProductEx(lpProductCode,
INSTALLLEVEL_DEFAULT,
INSTALLSTATE_DEFAULT,
tszNoReboot);
if (ERROR_SUCCESS_REBOOT_REQUIRED == uiReturn)
{
// prompt for reboot at the end of all modules uninstallation.
}
if (ERROR_SUCCESS != uiReturn)
{
// log message with return code.
// Error Code: 1605 is coming from here.
}
}
}while (ERROR_NO_MORE_ITEMS != status);
}
Some years have passed and I want to add two scipts that can be used to export MSI package information: How can I find the product GUID of an installed MSI setup? - in section 2.
Do visit the link above, but here are direct links to the scripts:
1)
the html export version and2)
the simpler text output.
Disclaimer: The below information is very "under the hood". Please use API calls whenever you can to access the MSI database. Also remember to run all your MSI testing on virtual machines so you can easily revert to a "clean state". During MSI development strange things can happen.
It is possible that a previous uninstall of that product of yours left something registered upon uninstall, and this is causing all the problems. I would try to check with scripts what is registered on the system.
Found good discussions of retrieving product info with VBScript here, a couple of really good scripts - recommended. Go to the sites to find the scripts, they format pretty poorly here and clog the answer.
The Windows Installer database is mostly located here:
You must never touch anything in the Windows Installer Database Registry directly. It's extremely interconnected and easy to corrupt. Only go through the APIs. Note that the GUIDs in the registry are packed, so you won't find the GUIDs from the package in the registry.
Using the VBScripts above and the registry data directly for inspection you should be able to determine what is happening in the Windows Installer database.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With