MsiEnumProductsEx (msi)
Last changed: janiek.buysrogge@gmail.com-194.78.138.114

.
Summary
The MsiEnumProductsEx function enumerates through one or all the instances of products that are currently advertised or installed in the specified contexts. This function supersedes MsiEnumProducts.

C# Signature:

[DllImport("msi.dll",
        EntryPoint="MsiEnumProductsExW",
        CharSet = CharSet.Unicode,
        ExactSpelling=true,
        CallingConvention=CallingConvention.StdCall)]
public static extern uint MsiEnumProductsEx(
        string szProductCode,
        string szUserSid,
        uint dwContext,
        uint dwIndex,
        string szInstalledProductCode,
        out object pdwInstalledProductContext,
        string szSid,
        ref uint pccSid)

User-Defined Types:

    public enum MSIINSTALLCONTEXT
    {
        MSIINSTALLCONTEXT_NONE      =   0,
        MSIINSTALLCONTEXT_USERMANAGED   =   1,
        MSIINSTALLCONTEXT_USERUNMANAGED =   2,
        MSIINSTALLCONTEXT_MACHINE       =   4,
        MSIINSTALLCONTEXT_ALL       = (MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED | MSIINSTALLCONTEXT_MACHINE),    
    }

Alternative Managed API:

Do you know one? Please contribute it!

Notes:

You can use this to query product codes from a Windows Service running under the local system account.

Tips & Tricks:

Please add some!

Sample Code:

    public static bool FindByProductCode(Guid productCode, ref string productName)
    {
        try
        {
        string codeToFind = productCode.ToString("B").ToUpper();

        var code = new string(new char[40]);        
        object junk = null;
        string szSid = new string(new char[300]);
        uint pccSid = 300;

        uint res = MsiInterop.MsiEnumProductsEx(codeToFind, null, (uint)MsiInterop.MSIINSTALLCONTEXT.MSIINSTALLCONTEXT_USERUNMANAGED, 0, code, out junk, szSid, ref pccSid);

        if (res == 0)
        {
            uint valueSize = 1024;
            var valueProductName = new string(new char[valueSize]);

            MsiInterop.MsiGetProductInfo(code, MsiInstallerProperty.ProductName, valueProductName, ref valueSize);

            productName = valueProductName;

            return true;
        }          
        }
        catch (Exception ex)
        {
        Console.WriteLine("Exception: " + ex.Message);
        }

        return false;
    }
    }

Documentation