Whilst working with the MSI Interop API I have come across some unusual behaviour which is causing my application to crash. It is simple enough to 'handle' the problem but I would like to know more about 'why' this is happening.
My first call to MSIEnumRelatedProducts returns an value of 0 and correctly sets my string buffer to a productcode. My understanding is that this would only happen if the given upgradecode (passed as a parm to the method) has a 'related family product' currently installed, otherwise it would return 259 ERROR_NO_MORE_ITEMS.
However when I subsequently call MSIGetProductInfo using the same productcode I get the return value 1605, "This action is only valid for products that are currently installed.".
Does anyone have any ideas under what circumstances this might happen? It is 100% repeatable on 1 machine but I have not yet managed to get reproduction steps on another machine.
All our products are build with the Wix Property "AllUsers=1" so products should be installed for all users, not just one.
Any ideas/suggestions appreciated.
Thanks Ben
Update: I've noticed that when running the problem msi package with logging the following line is shown:
MSI (s) (88:68) [12:15:50:235]: FindRelatedProducts: could not read ASSIGNMENTTYPE info for product '{840C...etc.....96}'. Skipping...
Does anyone have any idea what this might mean?
Update: Code sample.
do
{
result = _MSIApi.EnumRelatedProducts(upgradeCode.ToString("B"), 0,
productIndex, productCode);
if (result == MSIApi.ERROR_BAD_CONFIGURATION ||
result == MSIApi.ERROR_INVALID_PARAMETER ||
result == MSIApi.ERROR_NOT_ENOUGH_MEMORY)
{
throw new MSIInteropException("Failed to check for related products",
new Win32Exception((Int32)result));
}
if(!String.IsNullOrEmpty(productCode.ToString()))
{
Int32 size = 255;
StringBuilder buffer = new StringBuilder(size);
Int32 result = (Int32)_MSIApi.GetProductInfo(productCode,
MSIApi.INSTALLPROPERTY_VERSIONSTRING,
buffer,
ref size);
if (result != MSIApi.ERROR_SUCCESS)
{
throw new MSIInteropException("Failed to get installed version",
new Win32Exception(result));
}
version = new Version(buffer.ToString());
}
productCode = new StringBuilder(39);
productIndex++;
}
while (result == MSIApi.ERROR_SUCCESS);
See Question&Answers more detail:os