Search code examples
comregasm

Several short questions about COM .net assemblies, regasm, dll, tlb and guids


All question are related to a .net project dll in .net framework 2.0 that exposes itself as COM.

1) If we don't specify any GUIDs in the source code (typelib, classes, interfaces) who is generating the GUIDs? The compiler or regasm?

2) The GUIDs values exists in the dll, in the tlb or in both files?

3) Any developer with the same source code would generate the very same GUIDs independently on the machine where she builds or run regasm?

4) If I run regasm passing existing dll and tlb files, what happens If the dll and the tlb doesn't match? Regasm regenerate the tlb file with uptodate elements and GUIDs? Or it registers the TypeLib with the current tlb file?

5) What is the point of running regasm with dll and tlb parameters set? Tlb file is part of what you deploy or it is best practice to only deploy the dll and let regasm generate the tlb on the fly?

6) And last question, is tlb really required? What is the point of having a tlb file? Is not all the information already in the registry? What extra info it provides?

7) When unregistering with regasm, what we need to provide? The dll? The Tlb? Both? What happens if dll (or tlb) doesn't match with existing reg entries? If already registered with tlb option but I run regasm unregister with dll only it would delete the TypeLyb entry too?

8) Regarding bitness, regasm will always generate entries under SysWow64 too? The regasm under Framework64 do the same as the one under Framework?


Solution

  • A type library is the exact equivalent of .NET metadata. It is most of all useful to the client programmer, it makes the compiler and the IDE smart about your library. Providing auto-completion and syntax checking so the odds of a mismatch between his code and yours are minimal. The registration step is necessary so your files can be found back. The type library is normally embedded as a resource in the DLL itself, like .NET metadata, but the .NET build model does not make that easy to do. The client compiler uses the type library info to generate the appropriate COM calls. Guids are a big deal because that is what the client compiler needs to use, identifier names play no role. There is a way to use "late binding" using names, the exact equivalent of Reflection in .NET, but that does not involve a type library.

    who is generating the GUIDs?

    The CLR does. Every .NET interface or class has one, regardless if it is [ComVisible(true)]. Exposed also through the Type.GUID property. If you didn't use the [Guid] attribute on the type then it runs an algorithm to generate the Guid that uses the type declaration as input. Or in other words, if you make any changes to the type then you can be sure that the Guid will have a different value. Which is the basic reason you should never use the [Guid] attribute, unless you have to create an exact drop-in replacement and cannot recompile client code. The TLBID comes from the AssemblyInfo.cs file that was auto-generated when you created the project.

    in the dll, in the tlb or in both files?

    It only exists in the DLL when you used the [Guid] attribute, but normally it is generated at runtime as explained above. It is always present in the type library, that's how the client compiler knows to create an object of your class and use its interface(s).

    would generate the very same GUIDs

    Yes, only the type declaration plays a role.

    If I run regasm passing existing dll and tlb files

    Regasm can only create a type library, as requested with its /tlb option, it cannot take an existing one. It otherwise does the exact same thing as Tlbexp.exe does, use Reflection to enumerate the types in the assembly to find the [ComVisible(true)] ones and generate the matching type library declaration. The extra thing it does is write the registry key for the type library to HKLM/Software/Classes/Typelib. So the client IDE can find it back.

    What is the point of running regasm with dll and tlb parameters set?

    No real idea with "dll parameter" might mean. As noted above, use /tlb to generate the type library. Whether or not you deploy the type library depends on its usage, if you don't also provide the client code then you should always deploy it so the client programmer can use it. Other usage of the type library is the subject of this post. If you're not sure how the client programmer is going to use your code then always deploy.

    Is not all the information already in the registry?

    What's in the registry is limited, only enough info to find the type library file back. The description of your interfaces, their method signatures, guids and the CLSID that the factory function needs is in the type library.

    When unregistering with regasm, what we need to provide?

    Exact same thing as registering it, you only add /unregister. You must also provide /tlb if you used it previously so the TypeLib registry key can be deleted. It can be pretty important to automate this while you are busy developing and testing the library, since the guids are normally auto-generated you can produce a lot of garbage in the registry. As well as ugly head-scratching when you forget to run Regasm. Project > Properties > Build tab, "Register for COM interop" checkbox. But with the downside that you have to run VS elevated so it can write to the registry.

    regasm will always generate entries under SysWow64 too?

    SysWow64 plays no role, do always avoid deploying to c:\windows. But yes, bitness does matter, the registry is structured so a 64-bit app cannot accidentally create an object in a 32-bit library and die on an ugly exception. And the other way around. A 32-bit client app will read registry keys from HKLM/Software/WOW6432Node, you only get your registry keys there is you used the 32-bit version of Regasm. Notable perhaps is that it is usually fine to run both flavors of Regasm, given that C# code can run on any platform.