0

Does anyone know, how given a GUID that identifies an installed product, you can find the patches installed for that product with C#?

The application is quite complex and from time to time, we create patches (MSP files) through Orca/MSI. These patches can then be installed on the customer's computer and can then be viewed in "View Installed Updates" under Programs and Features.

I've tried two approaches:

  1. Using WMI I can find my product in Win32_Product and retrieve the information there. However, if I then query either Win32_PatchPackage or Win32_Patch for matches against the "ProductCode". I would have expected the captions/description to contain the information I want, but all I get is another separate set of GUIDs for each which doesn't seem very obvious what to do with it.

  2. Similarly, using the Registry I can find the Product (under HKLM\Software\Microsoft\Uninstall\\, and with some digging I can find Patches (under HKLM\Software\Microsoft\Installer\UserData\S-1-5-18\Products\) but the key isn't obvious. It isn't the same as my products installer GUID.

This question discusses similar issues, but the questioner was looking for the Windows patches, while I need my own applicaitons patches - so there solution doesn't really work for me.

Thanks in advance.

Community
  • 1
  • 1
Martin Clarke
  • 5,636
  • 7
  • 38
  • 58

1 Answers1

0

I was able to achieve this by plugging the ProductCode returned from Win32_PatchPackage into a Win32 dll and then using as so.

    [DllImport("msi.dll", CharSet = CharSet.Unicode)]
    internal static extern Int32 MsiGetPatchInfoEx(string szPatchCode, string szProductCode, string szUserSid, int dwContext, string szProperty, [Out] StringBuilder lpValue, ref Int32 pcchValue);

    // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa370128%28v=vs.85%29.aspx 
    // for valid values for the property paramater
    private static string getPatchInfoProperty(string patchCode, string productCode, string property)
    {
        StringBuilder output = new StringBuilder(512);
        int len = 512;
        MsiGetPatchInfoEx(patchCode, productCode, null, 4, property, output, ref len);
        return output.ToString();
    }

    public static string GetPatchDisplayName(string patchCode, string productCode)
    {
        return getPatchInfoProperty(patchCode, productCode, "DisplayName");
    }
Martin Clarke
  • 5,636
  • 7
  • 38
  • 58