Today I was testing some fresh code that I had written over the past weeks when I found I needed a fix from another developer. So I merged changes from the main branch into my local working copy and kicked off a deep rebuild. The build churned for a while but failed with some unusual errors, not the ordinary syntax errors. Aww nuts, the code was building fine before I got latest … but now I’m stuck until I fix this.
Ultimately the biggest problem was a circular dependency that I had introduced (it seems obvious now looking back) but that is not what this post is about. Along the way I ran into this nice little error that stumped me.
> regasm /verbose /tlb:CAP.SIFCatalogHandler.tlb CAP.SifCatalogHandler.dll
Types registered successfully
RegAsm : error RA0000 : Type library exporter encountered an error while processing 'CAP.SifCatalogHandler.SifCatalogHandler, CAP.SifCatalogHandler'. Error: Referenced type is defined in managed component, which is imported from a type library that could not be loaded (type: 'CAP.ICAPCatalog2'; component: 'C:\WINDOWS\assembly\GAC_MSIL\CAP.CAPDOM\1.0.0.0__414f99c4b6a0bb9a\CAP.CAPDOM.dll').
This error came up while trying to register a .NET assembly containing a COM object written in C#. Notice that this regasm.exe call also generates a TLB file. The error claims that it cannot load one of the referenced assemblies called CAP.CAPDOM.dll. This assembly is a runtime callable wrapper (RCW) for an older COM object written in C++. I checked and rechecked that CAP.CAPDOM.dll existed. I manually rebuilt it and checked again but I still kept getting the same error. I even pulled out fuslogvw.exe which showed that CAP.CAPDOM.dll was loading just fine.
Sigh, for once the tools give a detailed four-line error message that seems to say exactly what the problem is but I’m still to slow witted to figure it out.
A few Google searches on this error and I found a number of posts that seemed to generally confirm some sort of dependency error but nothing gelled. Besides, I already confirmed that the assembly its complaining about actually exists!
Finally I had an idea. CAP.CAPDOM is a RCW for a COM object. The RCW exists, but does the COM object? No. Does it need to? I didn’t know the answer at the time but it does need to exist in this case. This is when I realized I had a circular dependency. I backed out my changes and built the actual COM object.
This time regasm.exe worked correctly. Hooray!
I then unregistered the COM object to see what would happen and again the regasm.exe command gave the same error. Notice that the error text above actually says “Types registered successfully”. It seems to just fail while generating the TLB. Perhaps the RCW’s real COM object is only needed when generating a TLB like this. Perhaps its only needed when the assembly implements an interface originally declared in the missing COM object. Apparently the RCW alone is enough to code against and compile the project, but not enough to register it with regasm.exe. Turns out the beautiful four-line error message is spot on and like usual the problem exists between the keyboard and the chair.
The moral of the story is that an assembly load error for an RCW assembly might actually mean the RCW’s COM object DLL is missing.
I will remember that.
Now I just need to orchestrate something to get around the circular dependency, restore my changes and I’m back in business.