How to query COM class Version for packaged COM extension points?

Copper Contributor

I work on a plugin-based application that is currently scanning the Windows registry for compatible COM servers that expose certain "Implemented Categories" entries. This works well for "regular" COM servers installed through MSI installers. However, I'm now facing a problem with COM servers installed through MSIX installers that expose COM extension points through the "Packaged COM" catalog as described in


I've already begun to replace the registry search with ICatInformation::EnumClassesOfCategories that also scans the "Packaged COM" catalog. This seem to work nicely. However, I also need to access the COM class Version for compatibility checking.


Are there any Windows APIs for determining COM class Version that I can use instead of reading it directly from the registry?

2 Replies
best response confirmed by forderud (Copper Contributor)

@forderud thank you for your question. I asked some folks to try and get the best answer for you.


The OLE registration APIs (e.g. OleRegGetUserType) can provide the same properties for Packaged COM classes as they do for CLSID keys in the registry. The APIs don’t cover the full set of subkeys/values that are meaningful for CLSIDs though, and in particular not Version (assuming this refers to the Version (COM) - Win32 apps | Microsoft Docs subkey) or InprocServer32/LocalServer32.

For the most part these API omissions are intentional and reflect the intended usage, though the specific rationale varies, e.g.:

  • Version is part of a convention for a very narrow purpose (along with TypeLib, which is not mentioned in CLSID Key - Win32 apps | Microsoft Docs, but see ActiveX Controls Registry Information - Win32 apps | Microsoft Docs). TypeLib/Version enable late binding of type definitions for scripts calling class-specific interfaces, which historically was part of Internet Explorer’s model for hosting ActiveX controls, but not a generally recommendable pattern due to security and versioning difficulties. These have never been meaningful to COM activation or OLE so most class registrations don’t have this subkey, and for many that do at least among OS-provided registrations it appears this likely in error. I would caution against repurposing this even for the classic registry data contract, where of course an application could read it, because it is likely to be inconsistent with the original purpose.
  • InrprocServer32/LocalServer32 are intended as implementation details for activation, and other applications directly using them breaks the abstraction. Even for applications that have successfully used these details for unpackaged CLSID registrations in the registry – usage that we have never recommended in official documentation, though it is widely described elsewhere on the web – these techniques don’t generally work for Packaged COM registrations so it would be misleading to expose equivalents.
Thanks for the in-depth explanation @Aditi_Narvekar.

The Version entry is used for early compatibility checking for additional company-specific COM interfaces that have evolved over the years. It's nice to be able to filter out incompatible controls before instantiating them with CoCreateInstance. However, I can probably squeeze in the same information in "Implemented Categories" instead that still appear to be available.

The InprocServer32/LocalServer32 fields are similarly used for filtering out "broken" COM/OLE controls that have been registered but the EXE or DLL have since gone missing. This is not uncommon for developers who are building, registering & testing locally without going through a proper installer.