Demystifying COM Interop Assemblies


Sometimes, you'll come across COM registration keys that look like this:


But what are they exactly?   If you look at the registry keys created, you'll notice how it doesn't look like a normal COM DLL being registered (although its similar).  Normally, you'd have the InprocServer pointing to the DLL that's being registered, but in this case there's additional registry values being written that you wouldn't normally see that relate to the registration of a COM DLL.  

That's why you won't see these entries being placed into the Windows Installer advertising tables (ProgId, Class, etc), and that these entries appear in the Registry table.
 
Using regasm.exe to register the assembly as a COM DLL with the /codebase switch and exported the results into a .REG file to get the following:
REGEDIT4
[HKEY_CLASSES_ROOT\IPSMapControl.UserControl]
@="IPSMapAx.IPSMapControl"
[HKEY_CLASSES_ROOT\IPSMapControl.UserControl\CLSID]
@="{4F320749-E231-3312-8324-0ABEB73BBF18}"
[HKEY_CLASSES_ROOT\CLSID\{4F320749-E231-3312-8324-0ABEB73BBF18}]
@="IPSMapAx.IPSMapControl"
[HKEY_CLASSES_ROOT\CLSID\{4F320749-E231-3312-8324-0ABEB73BBF18}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="IPSMapAx.IPSMapControl"
"Assembly"="IPSMapAx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="
file:///c:/temp/checkpoint/ipsmapax.dll"
[HKEY_CLASSES_ROOT\CLSID\{4F320749-E231-3312-8324-0ABEB73BBF18}\InprocServer32\1.0.0.0]
"Class"="IPSMapAx.IPSMapControl"
"Assembly"="IPSMapAx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="
file:///c:/temp/checkpoint/ipsmapax.dll"
[HKEY_CLASSES_ROOT\CLSID\{4F320749-E231-3312-8324-0ABEB73BBF18}\ProgId]
@="IPSMapControl.UserControl"
[HKEY_CLASSES_ROOT\CLSID\{4F320749-E231-3312-8324-0ABEB73BBF18}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]

This is consistent with what's in the package.  In this particular case, this assembly offers backwards compatibility for older code like VB6 and .C++ so legacy applications can make use of the assembly's functions.  This is called COM Interop(erability), and from what I can gather - this is the only reason why you'd want to register the assembly (using regasm.exe).

 

Regasm.exe is a .NET Framework command-line utility that registers the assembly at the assembly's given location (to function like a COM DLL).  An assembly is just like a DLL, i.e. Shared groups of similar functional code contained within a .DLL.  The main difference is that assemblies generally aren't registered (thus avoiding DLL registration conflicts).  For example, if you look at my COMponent Manager tool, you'll see I have a .NET Assembly there called "Interop.WindowsInstaller.dll".  I use this in my code by referencing functions within that Assembly to perform anything to do with working with MSIs.  The reference is internal and isn't done via COM.  It is a private assembly because it sits in the same folder as my EXE, and the EXE expects to look for the assembly there by default (amongst a couple of other locations).


Shared assemblies should generally reside in the Global Assembly Cache, but there's nothing to force the developers to put the assembly there (much like how if you had a COM DLL like mscomctl.ocx, you can register this anywhere you like, but the convention is to put it in the SystemFolder.  When assemblies DON'T go into the GAC, the only way to make it appear 'global' is register it using regasm.exe with the /codebase parameter.  The /codebase is what tells the older application where to find the DLL.


So you may have noticed that there are parallels between the COM DLLs and Assemblies:

  • Regasm is similar to Regsvr32
  • Assemblies are similar to COM DLLs
  • C:\windows\system32 is the global store for DLLs that are to be registered and made available to the whole system.
  • C:\windows\assembly (i.e. the Global Assembly Cache) is similar to the above - where assemblies are registered and meant to be made available to any app - e.g. Office interoperability.  Assemblies going into the GAC require the assembly to have a strong name - i.e. to be signed using a public key token, have a unique name, have a version number, have a culture (i.e. specific to a region or language), and various other metadata describing the title, company, description, etc.

Additional reading and references:
How to register .NET Assembly for COM Interop
Registering Assemblies with COM
Side-by-Side Execution in the .NET Framework
About Isolated Applications and Side-by-side Assemblies


Comments

Popular posts from this blog

AppUserModelID & Disappearing Shortcuts in Windows 8

Sideloading Universal Windows Apps on Windows 10 (Deep Dive)

An alternative method of installing device drivers