regtlibv12怎么了?

JMK*_*JMK 29 windows-8 .net-4.5 visual-studio-2012 regtlib

我在分区上安装了Windows 8,安装了Visual Studio 11/2012 Professional,但在regtlibv12.exe内部找不到C:\Windows\Microsoft.NET\Framework\v4.0.30319.

下面是我的Windows 7分区的屏幕截图,其中包含.Net 4.0(和regtlibv12):

Windows 7  -  .Net 4

下面是带有.Net 4.5的Windows 8(并且没有regtlibv12):

Windows 8  -  .Net 4.5

regtlibv12不再.NET Framework的一部分?我是否还需要安装.Net 4.0?如果我在.4.0之上安装.Net 4.0会怎样?我知道他们都去了硬盘上的同一个位置,4.5有效地覆盖了4.0,而且在Windows 8上默认为4.5.我需要安装4.0,然后重新安装4.5以获得regtlibv12吗?

谢谢

Han*_*ant 38

它从来都不是框架的一部分.它完全没有记录.然而,有一个非常一致的谣言,很多程序员已经在他们的v2.0.50727或v4.0.30319目录中找到了它,并发现它可以解决注册问题.很多论坛帖子都提到了它.

它在这些文件夹中显示的确切方式很难进行逆向工程,我看到的唯一模式是,当您自己安装框架时它会存在.当框架预先安装在机器上时,它将不会存在.这有点意义,框架目录中有几个需要注册的.tlb文件.它们包含客户端代码可能依赖的.NET [ComVisible]类型的类型信息.正常方式类型库已注册不适用于那些.tlb文件,因为它们未嵌入常规COM服务器中.另外猜测,在预安装的.NET版本中不需要该工具,因为注册信息已汇总到常规Windows设置中.

如果你已经让自己依赖于该工具,那么除了从另一台机器上复制.exe之外你无法做很多事情.或解决您需要从另一端使用它的原因,因此您不再需要它:

  • 这是忘记在Regasm.exe中使用/ tlb选项的解决方法.当客户端代码尝试使用来自另一个线程的COM接口时,这可能会在运行时产生TYPE_E_CANTLOADLIBRARY错误.类型库提供了标准编组程序编组方法参数所需的类型信息.使用/ tlb选项来修复它.

  • 这是让COM服务器显示在Project + Add Reference,COM选项卡中的解决方法.该选项卡列出已注册的类型库.然而,这不是一个正确的解决方法,除了在构建服务器上,您可以编译您的代码,但由于注册未完成,您无法运行它.正确的方法是使用作者提供的安装程序或在压缩时使用Regsvr32.exe,以便注册类型库和CLSID键.

  • 它是未注册其类型库的COM服务器的变通方法.与上面类似,但注册类型库是可选的,通常只在开发机器上需要,而不是在运行服务器的机器上.大多数可以使用类型库的工具都可以显式添加它们,而不是依赖于TypeLib注册表项.Visual Studio IDE也是如此,您可以使用"浏览"选项卡直接选择.tlb文件.


Ian*_*emp 9

请参阅汉斯对所提出问题的出色回答;这个答案解释了如何获取上述可执行文件。

\n
    \n
  1. 安装 7-Zip 从从https://www.7-zip.org/download.html
  2. \n
  3. 从 下载 lessmsi/Les MSI\xc3\xa9rables从https://github.com/activescott/lessmsi/releases
  4. \n
\n

(或者你可以使用Chocolatey来安装以上两个:包名称是7ziplessmsi。)

\n
    \n
  1. 从以下位置下载 .NET Framework 4.0 独立安装程序从https://www.microsoft.com/en-gb/download/details.aspx?id=17718
  2. \n
  3. 使用 7-Zip 打开dotNetFx40_Full_x86_x64.exe上一步下载的文件,解压文件netfx_Core_x64.msinetFxCore.mzz临时目录
  4. \n
  5. 使用 lessmsi 打开netfx_Core_x64.msi,向下滚动文件列表并选择regtlibv12.exe(Component = 的那个)regtlibv12_exe_amd64,对于 x86 系统,或者两者都选择),然后单击“提取”按钮
  6. \n
  7. 浏览并选择要将文件解压到的目录,单击“确定”
  8. \n
  9. 瞧,你现在有了regtlibv12.exe
  10. \n
\n
    \n
  • 注:我不是律师,不知道上述内容是否违反任何法律,如果违反法律并给您带来麻烦,我也不承担任何责任。至少,不要重新分发regtlibv12.exe(无论这样做是非法的,如果您认为需要的话,您要么不需要,要么您的软件有很大问题)。
  • \n
\n


Art*_*zin 5

您可以使用 PowerShell 注册类型库。该脚本使用一小段 C# 代码,该代码又调用 WinApi 函数LoadTypeLibEx。该脚本有一个参数,即类型库的路径。创造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"
}
Run Code Online (Sandbox Code Playgroud)

使用批处理文件来启动脚本很方便;它只是将参数传递给脚本:

powershell -ExecutionPolicy ByPass -NoProfile -Command "& '%~dp0\RegisterTypeLib.ps1'" %*
Run Code Online (Sandbox Code Playgroud)

此外,以下脚本可用于取消注册类型库。这有点棘手,但效果很好:

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)
Run Code Online (Sandbox Code Playgroud)

  • @JMK,我只需要做同样的事情,并认为几个 powershell 脚本可能会帮助其他人:) (2认同)