COM Interop

Greg writes about some of the COM Interop quirks he's been struggling with lately.

Awhile back I wrote a Windows service that allowed you to monitor file system changes. The config file allowed you to register a directory to be watched and an assembly to call when something changed.

In one scenario, we wanted to monitor additions to a particular directory and perform some business logic that we previously implemented in a COM component - so the obvious solution was to use COM Interop. Originally, we just added a reference, and called the COM through the generated stub assemblies. The only problem was, as Greg mentioned, was that as soon as someone came along and recompiled this DLL, all hell broke loose.

Upon further investigation, it seems the reference is bound to a particular version of the DLL. The best workaround we found was to use a late-bound approach, creating an instance based on ProgId instead of through the stub assembly. It's a little "messier", but acts as a good buffer from changes to this DLL (even interface changes).

Type t = Type.GetTypeFromProgID("SomeCOM.ProgId");
Object o = Activator.CreateInstance(t);
object[] paramList = new object[1];
paramList[0] = "If you need params";
t.InvokeMember("YourMethod",BindingFlags.Public | BindingFlags.InvokeMethod,null,o,paramList);

Recompiling the assembly each time the COM component changed wasn't a solid approach, even in our scenario where it's deployed on a central server and we had a reasonable amount of control over the DLL in question.  Furthermore, it's thoroughly unrealistic if the COM is third-party or if this was deployed to many machines and/or machines beyond your control. These should not be tightly coupled objects.

Hope this helps.

Engineering