Hmm,
I can't believe this would make it through some basic testing but here
goes... I am attempting to detect the state of a product (VC 2005 Runtime)
using the following snippet.
<util:ProductSearch Id="SearchForVC2005SP1REDIST"
Guid="837B34E3-7C30-493C-8F6A-2B0F04E2912C" Variable="VC2005SP1Installed"
Result="version"/>
<util:ProductSearch Id="SearchForVC2005SP1MFCLOCREDIST"
Guid="710F4C1C-CC18-4C49-8CBF-51240C89A1A2" Variable="VC2005SP1MFCLOCInstalled"
Result="state"/>
When I use a result other than state, then the search functions as expected,
however if I use state it fails and the log file shows:
[2DB4:40F8][2012-06-14T12:57:17]: Error 0x80070648: Failed to get product info.
[2DB4:40F8][2012-06-14T12:57:17]: MsiProductSearch failed: ID
'SearchForVC2005SP1MFCLOCREDIST', HRESULT 0x80070648
Looking at code for Burn, I see the following:
search.cpp
static HRESULT MsiProductSearch(
__in BURN_SEARCH* pSearch,
__in BURN_VARIABLES* pVariables
)
{
HRESULT hr = S_OK;
LPWSTR sczProductCode = NULL;
LPCWSTR wzProperty = NULL;
BURN_VARIANT_TYPE type = BURN_VARIANT_TYPE_NONE;
BURN_VARIANT value = { };
switch (pSearch->MsiProductSearch.Type)
{
case BURN_MSI_PRODUCT_SEARCH_TYPE_VERSION:
wzProperty = INSTALLPROPERTY_VERSIONSTRING;
break;
case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE:
wzProperty = INSTALLPROPERTY_LANGUAGE;
break;
case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE:
wzProperty = INSTALLPROPERTY_PRODUCTSTATE; <!-This would happen -->
break;
case BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT:
wzProperty = INSTALLPROPERTY_ASSIGNMENTTYPE;
break;
}
// format product code string
hr = VariableFormatString(pVariables,
pSearch->MsiProductSearch.sczProductCode, &sczProductCode, NULL);
ExitOnFailure(hr, "Failed to format product code string.");
// get product info
value.Type = BURN_VARIANT_TYPE_STRING;
hr = WiuGetProductInfo(sczProductCode, wzProperty, &value.sczValue);
if (HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) == hr)
{
LogStringLine(REPORT_STANDARD, "Product not found: %ls",
sczProductCode);
// set value to indicate absent
switch (pSearch->MsiProductSearch.Type)
{
case BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT: __fallthrough;
case BURN_MSI_PRODUCT_SEARCH_TYPE_VERSION:
value.Type = BURN_VARIANT_TYPE_NUMERIC;
value.llValue = 0;
break;
case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE:
// is supposed to remain empty
break;
case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE:
value.Type = BURN_VARIANT_TYPE_NUMERIC;
value.llValue = INSTALLSTATE_ABSENT;
break;
}
hr = S_OK;
}
ExitOnFailure(hr, "Failed to get product info.");
// change value type
switch (pSearch->MsiProductSearch.Type)
{
case BURN_MSI_PRODUCT_SEARCH_TYPE_VERSION:
type = BURN_VARIANT_TYPE_VERSION;
break;
case BURN_MSI_PRODUCT_SEARCH_TYPE_LANGUAGE:
type = BURN_VARIANT_TYPE_STRING;
break;
case BURN_MSI_PRODUCT_SEARCH_TYPE_STATE: __fallthrough;
case BURN_MSI_PRODUCT_SEARCH_TYPE_ASSIGNMENT:
type = BURN_VARIANT_TYPE_NUMERIC;
break;
}
hr = BVariantChangeType(&value, type);
ExitOnFailure(hr, "Failed to change value type.");
// set variable
hr = VariableSetVariant(pVariables, pSearch->sczVariable, &value, FALSE);
ExitOnFailure(hr, "Failed to set variable.");
LExit:
if (FAILED(hr))
{
LogStringLine(REPORT_STANDARD, "MsiProductSearch failed: ID '%ls',
HRESULT 0x%x", pSearch->sczKey, hr);
}
ReleaseStr(sczProductCode);
BVariantUninitialize(&value);
return hr;
}
wiutil.cpp
extern "C" HRESULT DAPI WiuGetProductInfo(
__in_z LPCWSTR wzProductCode,
__in_z LPCWSTR wzProperty,
__out LPWSTR* psczValue
)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
DWORD cch = WIU_GOOD_ENOUGH_PROPERTY_LENGTH;
hr = StrAlloc(psczValue, cch);
ExitOnFailure(hr, "Failed to allocate string for product info.");
er = vpfnMsiGetProductInfoW(wzProductCode, wzProperty, *psczValue, &cch);
if (ERROR_MORE_DATA == er)
{
++cch;
hr = StrAlloc(psczValue, cch);
ExitOnFailure(hr, "Failed to reallocate string for product info.");
er = vpfnMsiGetProductInfoW(wzProductCode, wzProperty, *psczValue,
&cch);
}
hr = HRESULT_FROM_WIN32(er);
ExitOnFailure(hr, "Failed to get product info.");
LExit:
return hr;
}
When looking at the relevant documentation MsiGetProductInfo
(http://msdn.microsoft.com/en-us/library/windows/desktop/aa370130(v=vs.85).aspx)
and MsiGetProductInfoEx
(http://msdn.microsoft.com/en-us/library/windows/desktop/aa370131(v=vs.85).aspx)
, It seems to me that INSTALLPROPERTY_PRODUCTSTATE is only applicable when
calling MsiGetProductInfoEx which the wrapper WiuGetProductInfo does not do. Is
this a bug in Burn, or is Result="state" just not documented properly for its
shortcomings on the burn side?
If it is intended to work, then is anyone aware of a current bug or feature
request logged for it? (If not I can log one.) I understand it would be a bit
convoluted, as we would have to test for per user/machine contexts.
Thanks,
Jacob
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
WiX-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wix-users