Reputation: 45272
I am using the msi windows api to programmatically manage some installed programs.
I have the case where I know the Product
code, but I wish to find all of the Components
that relate to this product.
I know how to enumerate through all of the components in the system, and to query the component's product code. So an obvious solution is to just iterate through all of these components, and perform a string comparison on the product ids. (See the code below).
But this performs badly. On my machine this code is searching through 37,601 components to find the 8 components that match.
Is there some API call which, given the product identifier, lists just the components of that product?
do
{
// productGuid is a std::wstring
TCHAR componentBuffer[39];
msiReturn = ::MsiEnumComponents(componentIndex++, componentBuffer);
if(msiReturn != ERROR_NO_MORE_ITEMS)
{
TCHAR productBuffer[39];
UINT productReturnCode = ::MsiGetProductCode(componentBuffer, productBuffer);
if(productGuid == productBuffer)
{
// Add this to the matching component ids
}
}
}
while (msiReturn != ERROR_NO_MORE_ITEMS);
Upvotes: 3
Views: 940
Reputation: 55600
Take a look at the MsiGetProductInfo function and it's INSTALLPROPERTY_LOCALPACKAGE property. This should be able to return you a path to the cached MSI in [WindowsFolder]Installer and from there you should be able to use MsiOpenDatabase and other related functions to query the Component table to get the information you are looking for.
Upvotes: 4