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

.
Summary
Enumarates PatchCodes of all patches installed above specified product, even if this patches was superseded or obsolete.

C# Signature:

        [DllImport("msi.dll", EntryPoint="MsiEnumPatchesExW",
             CharSet=CharSet.Unicode, ExactSpelling=true,
             CallingConvention=CallingConvention.StdCall)]
        private static extern uint MsiEnumPatchesEx(string szProductCode,
            string szUserSid,
            uint dwContext,
            uint dwFilter,
            uint dwIndex,
            StringBuilder szPatchCode,
            StringBuilder szTargetProductCode,
            out object pdwTargetProductContext,
            StringBuilder szTargetUserSid,
            ref uint pcchTargetUserSid);

VB Signature:

Declare Function MsiEnumPatchesEx Lib "msi.dll" (TODO) As TODO

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:

This function is available starting with Windows Installer version 3.0.

Tips & Tricks:

Please add some!

Sample Code:

using WindowsInstaller;

    // Get all patches of per-machine installed product
    public  static  StringCollection getAllPatches(String productCode)
    {
        StringCollection retList = new StringCollection();
        Installer installer = (Installer)new WindowsInstaller();
        if (new Version(installer.Version) < new Version("3.0"))
        {
            StringList patchCodes = installer.get_Patches(productCode);
            if (patchCodes != null)
                foreach(string patchCode in patchCodes)
                {
                    retList.Add(patchCode);
                }
        }
        else
        {
            StringBuilder szPatchCode = new StringBuilder(40);
            StringBuilder szTargetProductCode = new StringBuilder(40);
            StringBuilder szTargetUserSid = new StringBuilder(300);
            uint pcchTargetUserSid = 300;
            object junk = null;
            for (uint i = 0; ; i++)
            {
                uint res = MsiEnumPatchesEx(
                    productCode, // Product code. Method enumerate only patches which applyed to specified product
                    null, // User SID. null needs if context == MachineContext only (4), it means to use only per-machine installations
                    4, // Installation context. 4 means MachineContext only.
                    7, // Filter bitmask. 7 means to search applyed, superseded and obsolete
                    i, // iterator
                    szPatchCode, // Return value of currently found PatchCode
                    szTargetProductCode,  // Equals to ProductCode
                    out junk,
                    szTargetUserSid, // User SID. Indicate owner of this installation. (Here is null)
                    ref pcchTargetUserSid // Length of user SID
                );
                if (res == 0)
                    retList.Add(szPatchCode.ToString());
                else
                    break;
            }
        }
        return retList;
    }

Documentation