What happened to regtlibv12?
Asked Answered
R

3

37

I have a clean install of Windows 8 on a partition, with Visual Studio 11/2012 Professional installed and I cannot find regtlibv12.exe inside C:\Windows\Microsoft.NET\Framework\v4.0.30319.

Below is a screenshot of my Windows 7 partition, with .Net 4.0 (and regtlibv12):

Windows 7 - .Net 4

Below is Windows 8 with .Net 4.5 (and no regtlibv12):

Windows 8 - .Net 4.5

Is regtlibv12 no longer a part of the .Net framework? Do I need to install .Net 4.0 as well? What would happen if I installed .Net 4.0 over the top of 4.5? I know that they both go to the same location on the hard drive, and 4.5 effectively overwrites 4.0, and 4.5 comes as default on Windows 8. Would I need to install 4.0, and then re-install 4.5 to get regtlibv12 back?

Thanks

Rowenarowland answered 7/10, 2012 at 14:16 Comment(0)
C
42

It was never part of the framework. And it is entirely undocumented. There is however a very consistent rumor that it is, lots of programmers have found it in their v2.0.50727 or v4.0.30319 directories and figured out that it could solve registration problems. Lots of forum posts mention it.

The exact way it shows up in those folders is hard to reverse-engineer, the only pattern I've seen is that it will be there when you install the framework yourself. And won't be there when the framework is pre-installed on the machine. Which somewhat makes sense, there are several .tlb files in the framework directory that need to be registered. They contain type info for .NET [ComVisible] types that client code may have a dependency on. The normal way type libraries get registered does not apply for those .tlb files since they are not embedded in a regular COM server. With the additional guess that the tool isn't needed in a pre-installed version of .NET because the registration info is rolled-up into the regular Windows setup.

If you've gotten yourself into a dependency on the tool then you can't do much beyond copying the .exe from another machine. Or tackle the reason you need to use it from the other end so you don't need it anymore:

  • it is a workaround for forgetting to use the /tlb option with Regasm.exe. That may produce a TYPE_E_CANTLOADLIBRARY error at runtime when client code tries to use a COM interface from another thread. The type library provides the type info that the standard marshaller needs to marshal the arguments of the method. Use the /tlb option to fix that.

  • it is a workaround for getting COM servers to show up in the Project + Add Reference, COM tab. That tab lists registered type libraries. It is however not a proper workaround, other than on build servers, you can compile your code but you can't run it since the registration is not complete. The proper way to do it is by using the author's provided installer or by using Regsvr32.exe in a pinch so both the type library and the CLSID keys get registered.

  • it is a workaround for COM servers that don't register their type library. Similar as above, but registering type libraries is optional and typically only required on your dev machine, not on the machine that runs the server. Most tools that can consume type libraries have a way to add them explicitly rather than depend on the TypeLib registry key. So does the Visual Studio IDE, you can use the Browse tab instead to select the .tlb file directly.

Chairborne answered 7/10, 2012 at 16:15 Comment(7)
Very interesting, if I figure out how it got onto my machine originally I will leave a comment, however I didn't install the framework myself on the Windows 7 partition, it installed alongside Visual Studio, just like it did whenever I installed Visual Studio on Windows 8Rowenarowland
No, there's a major difference. .NET 4.5 comes pre-installed on Windows 8.Chairborne
Sorry of course, and 3.5 comes pre-installed on Windows 7, you install 4 when you install Visual Studio 2010.Rowenarowland
I had this issue with InDesign CS3. RegAsm / tlb did not recognize the InDesign .tlb So I copied the regtlibv12 from Windows.old and it worked just fine. (Not my fault Adobe has not modernized their type library lol)Sheaff
Hmya, you should never use Regasm on an unmanaged COM component like InDesign. All that does is corrupt the registry entries that the Adobe installer created. Regasm must only ever be used when you create your own [ComVisible(true)] .NET assembly. Reinstalling the product is required to recover from the registry damage.Chairborne
Thanks so much @HansPassant, I've been trying to figure out why the /tlb option is required when installing our software. Apparently VS calls regasm.exe with the /tlb and /codebase options when compiling which is why our code was working in our Dev environments, but not on clean machines. I hacked in some code and noticed if I fired the events on the main thread (which happens to be the same thread the COM object was created on) it worked on client machines. Now I think I understand the root cause. "The type library provides the type info that the marshaler needs to marshal the arguments"Hwang
So in my installer, if I call regasm with the /tlb flag and immediately delete the resulting .tlb file (so my installer doesn't have to worry about cleaning it up later during uninstall) Is all of the resulting typelib info needed for the marshaller safely tucked away in the registry? (It seems that way from my Tests, but I want to be sure)Hwang
D
9

Refer to Hans' excellent answer to the question as posed; this answer explains how to get hold of the aforementioned executable.

  1. Install 7-Zip from https://www.7-zip.org/download.html
  2. Download lessmsi/Less MSIérables from https://github.com/activescott/lessmsi/releases

(Or you can use chocolatey to install both of the above: package names are 7zip and lessmsi respectively.)

  1. Download the .NET Framework 4.0 Standalone Installer from https://www.microsoft.com/en-gb/download/details.aspx?id=17718
  2. Use 7-Zip to open the downloaded dotNetFx40_Full_x86_x64.exe from the previous step, extract the files netfx_Core_x64.msi and netFxCore.mzz to a temporary directory
  3. Use lessmsi to open netfx_Core_x64.msi, scroll down the file list and select regtlibv12.exe (the one with Component = regtlibv12_exe_amd64 for an x64 system, the other one for x86, or both if you need both) and click the "Extract" button
  4. Browse for and select the directory you want to extract the files to, click OK
  5. Et voila, you now have regtlibv12.exe!
  • Note: I am not a lawyer and am unaware if the above violates any laws, nor can I be held liable if it does and gets you into trouble. At the very least, do not redistribute regtlibv12.exe (regardless of the fact that doing so would be illegal, if you think you need to - you either don't, or your software has big problems).
Draughtsman answered 4/6, 2020 at 11:32 Comment(0)
I
5

You can use PowerShell to register a typelib. The script uses a small piece of C# code, that in its turn calls WinApi function LoadTypeLibEx. The script has a single argument, a path of the typelib. Create RegisterTypeLib.ps1:

param($path)

Write-Host $path

$signature = @'
[DllImport("oleaut32.dll", CharSet=CharSet.Unicode, ExactSpelling=true, SetLastError=true)]
public static extern int LoadTypeLibEx(string fileName, uint regkind, out System.Runtime.InteropServices.ComTypes.ITypeLib typeLib);
'@

$type = Add-Type -MemberDefinition $signature `
    -Name Win32Utils -Namespace LoadTypeLibEx `
    -PassThru
   
$typeLib = $null
$hr = $type::LoadTypeLibEx($path, 1, ([ref]$typeLib))
if ($hr -ne 0)
{
    throw "LoadTypeLibEx failed, hr = $hr"
}

It's handy to use a batch file to launch the script; it just passes the argument to the script:

powershell -ExecutionPolicy ByPass -NoProfile -Command "& '%~dp0\RegisterTypeLib.ps1'" %*

Additionally, the following script can be used to unregister a typelib. It's a bit tricky but works well:

param($path)

Add-Type -Language CSharp @'
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

namespace Helpers
{
    public static class TypeLibRegistration
    {
        [DllImport("oleaut32.dll", CharSet=CharSet.Unicode, ExactSpelling=true, SetLastError=true)]
        public static extern int LoadTypeLibEx(string fileName, uint regkind, out ITypeLib typeLib);

        [DllImport("oleaut32.dll", CharSet=CharSet.Unicode, ExactSpelling=true, SetLastError=true)]
        public static extern int UnRegisterTypeLib(ref Guid libID, ushort wVerMajor, ushort wVerMinor, uint lcid, uint syskind);

        public struct TLIBATTR
        {
            public Guid guid;
            public uint lcid;
            public uint syskind;
            public ushort wMajorVerNum;
            public ushort wMinorVerNum;
            public ushort wLibFlags;
        }

        public static void Unregister(string fileName)
        {
            ITypeLib typeLib;
            int hr = LoadTypeLibEx(fileName, 0, out typeLib);
            if (0 != hr)
                throw new Exception(string.Format("LoadTypeLibEx() failed, hr = {0}", hr));

            IntPtr libAttrPtr;
            typeLib.GetLibAttr(out libAttrPtr);

            TLIBATTR libAttr = (TLIBATTR)Marshal.PtrToStructure(libAttrPtr, typeof(TLIBATTR));

            hr = UnRegisterTypeLib(ref libAttr.guid, libAttr.wMajorVerNum, libAttr.wMinorVerNum, libAttr.lcid, libAttr.syskind);
            if (0 != hr)
                throw new Exception(string.Format("UnRegisterTypeLib() failed, hr = {0}", hr));
        }
    }
}
'@

[Helpers.TypeLibRegistration]::Unregister($path)
Intertwine answered 21/12, 2022 at 10:35 Comment(2)
Thanks, I actually asked this question in 2012 but appreciate the reply, interesting for sure!Rowenarowland
@JMK, I just needed to do the same and think that several powershell scripts might help others :)Intertwine

© 2022 - 2024 — McMap. All rights reserved.