S h o r t S t o r i e s

// Tales from software development

.NET Interop Assemblies and COM references

leave a comment »

A confusing tale of legacy COM libraries and .NET Interop…

The Problem

We have a COM library called VDataServer.dll that used to have a dependency on a third party COM library called Gordias.dll. Some time ago the calls that VDataServer made to Gordias were replaced with calls to newly implemented replacement functions in VDataServer.dll.

One of our .NET applications calls VDataServer via .NET Interop and although it’s worked successfully in the past we had some problems deploying it to a customer site last week. It was failing with a type initialisation exception when a function in VDataServer was called yet it worked on our development machines. Well, most of them – I found that I couldn’t even compile the application on my machine as it complained about a missing reference to the Gordias.dll.

I checked the VDataServer source code and found that while the calls to functions in the Gordias library had been removed, there were still references to the library. These references didn’t cause any loading or execution problems in a COM only execution environment but they seemed to be causing a load or initialisation failure when used from a .NET application.

I copied the Gordias library onto my machine and registered it, used TLBIMP to create interop assemblies for both VDataServer and Gordias, and added references to these assemblies to the .NET application project. The project still failed to compile with an error message indicating that there was a missing reference to the Gordias assembly.

I used Reflector to load the interop assembly for VDataServer and was surprised to find that when I expanded the reference to Gordias it prompted me to browse for the Gordias interop assembly even though it was in the same folder. So, there was something wrong with the reference to Gordias in VDataServer or with the Gordias interop assembly.

A Solution

It took a while for me to realise that because the dependency on Gordias was not a direct dependency but rather a dependency that VDataServer had, what was required was to create the interop assembly for Gordias first and then create the interop assembly for VDataServer using the /reference argument to tell TLBIMP to use the Gordias interop assembly to resolve references:

tlbimp.exe Gordias.dll /out:Interop.Gordias.dll

tlbimp.exe VDataServer.dll /out:Interop.VDataServer.dll /reference:Interop.Gordias.dll

When I deleted and re-added the references for the two interop assemblies to the .NET project it successfully compiled.

Finally, just to prove that the failure on the version deployed to the customer site was simply a Fusion binding failure, i.e. the .NET CLR loader process was unable to correctly resolve the reference to the Gordias interop assembly in the VDataServer interop assembly, I configured Fusion logging to write bind failures to disk. This confirmed that Fusion was trying and failing to resolve the reference to the Gordias interop assembly by incorrectly loading the Gordias COM dll.

It seems that we were somehow getting away with the problem previously because most of our development machines, and the customer servers where the application was deployed, had a copy of the Gordias dll. It’s still not completely clear how this worked when it seems that TLBIMP must be run with the /reference argument specifying the Gordias interop assembly because no one can remember having to do this previously.

Lessons learned

1. If there’s the slightest suspicion the problem is a Fusion binding failure then use Fusion’s logging to check this as it will save you a lot of time.

2. If you’re referencing a COM dll in a .NET project that references other COM dlls then you may find that you need to create .NET interop assemblies for the referenced COM dlls first and then specify these using TLBIMP’s /reference argument when creating the interop assembly for the .COM dll that your .NET code is calling.

Advertisements

Written by Sea Monkey

September 12, 2012 at 8:00 pm

Posted in Debugging, Development

Tagged with , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: