0

The product that I'm working on requires that a type library file (suffix .tlb) be registered for internal COM communication between components to work correctly. On production machines this registration is performed by the InstallShield setup. On developer machines, however, we so far depended on the utility regtlibv12.exe to do the job.

While upgrading our dev environment to Visual Studio 2017 (previously Visual Studio 2013) we found out that regtlibv12.exe is no longer present. A quick search through the entire machine for regtlib*, tlb*.exe and other likely patterns did not yield any result. Also, my Internet search-fu did not produce anything useful - but I simply may have used the wrong keywords...

Do you know of any utility that is deployed with Visual Studio 2017 that can replace regtlibv12.exe? Anything that can be run from a PowerShell script is acceptable. Also acceptable is a hint for the relevant .NET API that I could use to code the registration process myself (I might even go so far as to try to p/invoke Win32 functions). Not acceptable are solutions that need to be run as part of the build process - I don't want the type library to be registered on the build server!

In case this is important: The .tlb file is generated from a .NET assembly with tlbexp.exe.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
herzbube
  • 13,158
  • 9
  • 45
  • 87
  • It has never been a formally supported and documented tool. You could only find it back on machines that boot <= Win7, it was used by the framework installer. Won't be back, the framework install is now rolled-up in the OS install. If you use tlbexp.exe then you've just always used the wrong tool, use regasm.exe /tlb instead. Which creates the .tlb *and* registers it. – Hans Passant Jan 22 '18 at 14:34
  • @HansPassant That's exactly the thing we do **not** want - on the build server we want to create the .tlb but **not** register it. Registering the .tlb is necessary only at runtime, not at build time. But thanks for the information anyway. – herzbube Jan 22 '18 at 14:48
  • 1
    That is what tlbexp.exe does. Why you don't want to use it on the build server is not obvious. – Hans Passant Jan 22 '18 at 15:03
  • Why don't you just put the type library in the directory you need and reference it via manifest? Then you don't have to worry about registration crud. – Joseph Willcoxson Jan 22 '18 at 15:37
  • @JoeWillcoxson Interesting, will check this out... – herzbube Jan 22 '18 at 15:47
  • 1
    For example... syntax will be hosed, but here goes: ...obviously fill in the correct guids, etcs. Google for isolated COM – Joseph Willcoxson Jan 22 '18 at 15:49
  • @HansPassant I misunderstood your comment - I thought you suggested to generally replace tlbexp.exe by regasm.exe. I now understand that you mean to use tlbexp.exe on the build server, and regasm.exe on the dev machine. It's a valid suggestion, but it would also mean that on a dev machine I can't build without also registering the .tlb. Given how our dev team has to follow certain procedures to switch between source control branches, I'm not yet happy about this. I will first investigate the manifest suggestion. – herzbube Jan 22 '18 at 16:06
  • 1
    @herzbube, this is what's unclear to me: you're looking for a replacement for `regtlibv12` which *did* register the library, but you *no longer* want to register it? FWIW, see if [this](https://stackoverflow.com/a/23077042/1768303) helps. – noseratio Jan 23 '18 at 03:20
  • @Noseratio Please distinguish between runtime and build time. It is at build time that I do not want to register (and never did) because over time that would fill up the registry on the build server. Registration is also simply not necessary to build the product. Registration is only required to **run** the software. On a dev machine this typically happens when you start the program for a debug session. Thanks for the pointer to ‘RegistrationService‘. – herzbube Jan 23 '18 at 06:47
  • @herzbube, I'm well aware of that difference. So, how `regtlibv12` was useful to you *previously* during the *build* time? Or was it not? In which case, how did you handle it on the build server before VS2017? It is not quite clear to me from your question. Sounds like two independent questions in one. – noseratio Jan 23 '18 at 07:17
  • 2
    "fill up the registry"? If you don't change guids too often (why would you?), it will always create the same entries. Like others I don't understand what real problems you're trying to solve. Otherwise it's easy to write your own tools: https://stackoverflow.com/questions/23487332/how-to-programmatically-register-set-correct-path-to-a-type-library-from-withi – Simon Mourier Jan 23 '18 at 07:36
  • @Noseratio I never used `regtlibv12` during build time. I also never ran `regtlibv12` on the build server - why would I? The build server **builds** the software, it does not run it. Hence the sentence in the OP saying "Not acceptable [...]". – herzbube Jan 23 '18 at 08:02
  • @SimonMourier You are right in that `regtlibv12` does not add anything between builds as long as neither type library version nor GUID changes. The same is **not** true, however, when you register the assembly: Registering the assembly adds new entries to the registry whenever the assembly file version changes - and that happens in every build because our build system inserts a unique build ID as the last part of the file version. Because `regasm` not only registers the type library, but also registers the assembly, it will "fill up" the registry over time. – herzbube Jan 23 '18 at 09:51
  • @SimonMourier Oh and by the way, thanks for the pointer to the `RegisterTypeLib` Win32 API function. I'll first try the "isolated COM" approach suggested by @JoeWillcoxson, though, because that obviates the need for registering in the first place. Both of you: Feel free to write your comments as answers if you want to get a +1. – herzbube Jan 23 '18 at 10:15
  • 1
    Changing file version does *not* changes registration guids, only key values. If you want to register also by yourself, here is another link: https://stackoverflow.com/a/35789844/403671 PS: I don't answer question I don't understand, hence the comments. – Simon Mourier Jan 23 '18 at 12:41

1 Answers1

0

Following the suggestion by Joe Willcoxson (see OP comments), I ended up adding this snippet to our main executable manifest:

<file name="foo.tlb">
    <typelib
        tlbid="{EA4C1F13-2831-37CD-A94A-C761AF367506}"
        version="1.0"
        helpdir=""/>
</file>

As Joe mentioned, for this to work, the type library file has to be located in the same folder as the executable file that contains the manifest.

Specific to my situation, I was "lucky" because our main executable is as an out-of-process COM server, so when a client creates a COM object our main executable is launched as a separate process and our manifest takes effect. Had our COM object been in an in-process COM server, the client executable's manifest would have taken effect and I would have had to add the manifest snippet to the client executable.

As a final remark, I would like to add that this solution is probably not generally useful. What others could take away from here is that COM registration in the Windows registry can be obviated by a technique called "Isolated COM", which is also known as "Registration-Free COM". Whether you can take advantage of Registration-Free COM very much depends on how your COM servers and COM clients are deployed, and whether you have control over the manifests used by COM servers and clients.

As usual with COM, it's not a simple subject, but as a starting point for your research I can recommend the 2005 MSDN article Registration-Free Activation of COM Components: A Walkthrough, and its .NET companion Registration-Free Activation of .NET-Based Components: A Walkthrough.

herzbube
  • 13,158
  • 9
  • 45
  • 87