Problem: VC++ 2010 #import with no_registry fails with error C1083 or C3510


Symptoms


Compiling a C++ source file that contains a #import statement and the no_registry option when importing a type library for a managed assembly one of the following errors are emitted:

error C1083: Cannot open type library file: 'd:\code\lib\MyManagedComponent.tlb': Error loading type library/DLL. d:\code\testproject\testproject.cpp
or
error C3510: cannot locate dependent type library 'mscorlib.tlb' {bed7f4ea-1a96-11d2-8f08-00a0c9a6186d} v.2.4 d:\code\testproject\testproject.cpp 

Cause


There may be multiple versions of a type library for a managed assembly installed on a machine, but not all of them may be registered. For instance, when both .NET 4.0 and earlier versions of .NET (such as 2.0 or 3.5) are installed on the machine you may have the type library for the 2.0 version of a type library registered, but the type library for the 4.0 Framework version may not be registered. TlbExp.exe by default uses the registry to discover dependent type libraries and will use that version in the generated TLB file even if it doesn't match the version the managed assembly is referencing.

Also, there is a known issue that some System.Windows.Forms.tlb instances have a named dependency on oleacc.tlb, which probably does not reside anywhere on your machine. oleacc.dll is distributed with Windows, and it has an embedded type library, but the .tlb file was not distributed.

Resolution


TlbExp has a command line option /tlbrefpath that allows you to explicitly specify the path(s) to search to resolve .tlb references instead of relying on the registered type libraries. For instance, if you need to ensure that the .NET 4.0 version of the type libraries are referenced when .NET 2.0 is also present, and the 32-bit type libraries are found when on a 64-bit version of Windows, you could use an option like this (all on one line):

TlbExp MyManagedComponent.dll /tlbrefpath:C:\Windows\Microsoft.NET\Framework\v4.0.30319;c:\windows\syswow64\ 
If you also have a dependency on System.Windows.Forms.tlb, you may need to work around the reference to a non-existent oleacc.tlb. To do this, use Visual Studio to open (with the Resource Editor) the oleacc.dll, which you should find in the C:\Windows\System32 or C:\Windows\SysWow64 folder. Within the Resource Editor, you will observe that there a a few resources of "TYPELIB" type. Select the first one. Right-click on the item in the tree and choose Export. Name the file oleacc.tlb. Save this file into a folder that you will put in your /tlbrefpath. This will allow the reference to be resolved when the #import attempts to find dependencies without the aid of the registry (because of no_registry option).