Windows 64 位注册表与32 位注册表

Posted

技术标签:

【中文标题】Windows 64 位注册表与32 位注册表【英文标题】:Windows 64-bit registry v.s. 32-bit registry 【发布时间】:2010-10-26 13:38:21 【问题描述】:

我听说在 Windows x64 架构上,为了支持同时运行 x86 和 x64 应用程序,有两套单独/不同的 Windows 注册表——一套供 x86 应用程序访问,另一套供 x64 应用程序访问?例如,如果一个 COM 在 x86 注册表集中注册 CLSID,那么 x64 应用程序将永远无法通过 CLSID 访问 COM 组件,因为 x86/x64 有不同的注册表集?

那么,我的问题是我对上述示例的理解是否正确?我还想获得更多文档来学习这个主题,关于 x64 架构上的两组不同的注册表。 (我做了一些搜索,但没有找到任何有价值的信息。)

【问题讨论】:

【参考方案1】:

我运行 x64 位计算机作为我的桌面;而且我从未遇到过不同注册表配置的任何问题。

根据 MSDN,显然存在差异: http://msdn.microsoft.com/en-us/library/ms724072(VS.85).aspx

HTH

【讨论】:

【参考方案2】:

这是关于 WOW64 注册表的 Wikipedia 文章,它可能会为您提供一些您正在寻找的信息:

http://en.wikipedia.org/wiki/WOW64

【讨论】:

假设我有一个为任何 CPU 构建的 .Net 应用程序,并在 x64 上运行它,那么它应该被 JITed 以访问 x64 版本的注册表 - 即在 x64 注册表下注册的 COM 的 CLSID,如果我注册了一个 32 位 COM 组件,.Net 应用程序将无法找到它?我的理解正确吗?【参考方案3】:

你的理解是正确的。 x64 应用程序不需要访问 x86 CLSID,因为它永远无法加载这些组件,反之亦然。

如果您想创建供 x86 和 x64 使用的组件,那么您需要创建一对 dll,一个为 x86 构建,另一个为 x64 构建,并在注册表的相应部分注册。 System32文件夹中的regsrv32.exe会反注册x64组件,SysWOW64文件夹中的regsrv32.exe会注册x86组件。

或者为任何一种 CPU 架构都可以使用的任何 CPU 构建一个 .NET 程序集。

【讨论】:

@AnthonyWJones,我对您提到的 .Net Any CPU 示例感兴趣。假设我有一个为任何 CPU 构建的 .Net 应用程序,并在 x64 上运行它,那么它应该被 JITed 以访问 x64 版本的注册表 - 即在 x64 注册表下注册的 COM 的 CLSID?我的理解正确吗? 在这种情况下,它不是 JIT 或 .NET 来决定要查找 CLSID 的注册表的哪个部分,而是因为运行代码的进程是 64 位,这决定了它将使用哪个集查找 CLSID。这是在 Windows 中安装的 COM 支持库中自动发生的事情。 1.当我们使用 regsvr32 注册一个新的 COM 组件时,我们是在 x86 注册表下还是在 x64 注册表下或两者下都注册它? 2. 我的理解是,64位进程只能访问x64注册表为COM CLSID,32位进程只能访问x86注册表为COM CLISD,不能交叉访问。我的理解正确吗? 不清楚您是在创建 COM 组件还是尝试使用一个?我对 .NET 的引用与创建可在 32 位或 64 位进程中工作的程序集 dll 的能力有关。您是正确的,64 位进程无法加载 32 位 dll,反之亦然。 抱歉,我的问题没有说清楚。让我再说一遍。 :-) 对于原生 COM 组件,如果是 x86,则应使用 x86 版本的 regsvr32 将其注册到 x86 注册表,如果是 x64,则应使用 x64 版本的 regsvr32 将其注册到 x64 注册表。并且并非所有版本的原生 COM 组件都适合 x86/x64,因此我们只需注册一次,两个 x86/x64 进程都可以加载进程内 COM 组件。我的理解正确吗?【参考方案4】:

它们不是单独的注册表——一个是另一个的子节点,操作系统进行虚拟化以确保 32 位应用程序获取它们的密钥,而 64 位应用程序获取它们的密钥。

【讨论】:

上面发布的 MSND 文章可能是最好的起点。 msdn.microsoft.com/en-us/library/ms724072.aspx 一个小问题,如果我使用 regsvr32 注册 COM 组件,我们如何知道我们是在 x86 还是 x64 注册表下注册 COM 组件?我的困惑是,如果在 x86 注册表下注册,x64 应用程序将无法访问 COM 组件? 所以,这就是为什么我想知道它是在x86还是x64下注册的。我认为当我们使用 regsvr32 注册它时,我们在 x86 或 x64 下注册,而不是在两者下注册? 是的,您通常只注册为一个,因为您的控件将位于 32 位 DLL 或 64 位 DLL 中,并且您无法将 32 位控件加载到 64 位进程中(反之亦然)。因此,您可能希望分别注册 32 位和 64 位。但是,我从来没有这样做过,所以我不确定这是否是正确的做法...... 所以,如果我想为32位进程和64位进程构建一个COM组件,我需要注册两次并构建两个COM组件——x86构建和x64构建,并在 x64 注册表下注册一个,另一个在 x86 注册表下注册?【参考方案5】:

不久前我遇到了这个问题。简短的回答是,如果您在 64 位机器上运行 32 位应用程序,那么它的注册表项位于 Wow6432Node 下。

例如,假设您有一个应用程序将其注册表信息存储在:

HKEY_LOCAL_MACHINE\SOFTWARE\CompanyX

如果您将应用程序编译为 64 位二进制文​​件并在 64 位计算机上运行,​​则注册表项位于上述位置。但是,如果您将应用程序编译为 32 位二进制文​​件并在 64 位计算机上运行,​​那么您的注册表信息现在位于此处:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\CompanyX

这意味着如果您在同一台机器上同时运行 32 位和 64 位版本的应用程序,那么它们将各自查看一组不同的注册表项。

【讨论】:

一个小问题,如果我使用 regsvr32 注册一个 COM 组件,我们怎么知道我们是在 x86 还是 x64 注册表下注册的?我的困惑是,如果在 x86 注册表下注册,x64 应用程序将无法访问 COM 组件? 在 64 位机器上有两个版本的 regsrv32。一个在 Wow6432 节点中注册 64 位二进制文​​件和一个注册 32 位二进制文​​件。这篇 Microsoft 知识库文章可能对您有所帮助:support.microsoft.com/kb/282747 1.当我们使用 32 位 regsvr32 注册新的 COM 组件时,必须为 x86 构建 COM 组件(当我们使用 64 位 regsvr32 注册新的 COM 组件时,必须为 x64 构建 COM 组件)——意味着我们不能使用 32 位 regsvr32 注册 64 位 COM 组件(或使用 64 位 regsvr32 注册 32 位 COM 组件),对吗? 2. 64位进程只能访问x64注册表的COM CLSID,32位进程只能访问x86注册表的COM CLISD,不能交叉访问。我的理解正确吗? 这是我的理解,但我不提供任何保证:)。几个月前我只顺便处理过一次。 如果我为 x86 用户和 x64 用户开发原生 COM 组件目标,那么我需要提供两种不同的构建(x86 构建和 x64 构建)?无法通过只为原生构建提供一个构建并同时适用于 x86/x64 来保存我的工作?【参考方案6】:

如何注册 .NET 程序集以在纯 64 位应用程序中用作 COM?

问题: 默认情况下,如果您在构建设置中启用“注册 COM 互操作”,它不会为 64 位注册类型库。

解决方案: 要在 64 位机器上注册不在 GAC 中的程序集,请打开 cmd 窗口并执行以下操作:

cd c:\windows\microsoft.net\framework64\v2.x.xxxxx
regasm /codebase "path to your compiled assembly dll"

这将在使用本机 C++ 将 .NET 程序集实例化为 COM 对象时消除“类未注册错误”。

【讨论】:

这正是导致我的 64 位混合模式应用程序失败的原因 - 程序集是由 Visual Studio 2010 注册的 32 位 com。因此,我没有注册 COM 互操作,而是将构建后事件放到regasm 如上所述(在我的情况下使用 /TLB 生成)。是否有与此行为相关的 MSDN 文章?

以上是关于Windows 64 位注册表与32 位注册表的主要内容,如果未能解决你的问题,请参考以下文章

将 32 位 COM DLL 注册到 64 位 Windows 7

Wow6432Node(32位程序的注册表内容都在这个节点下,也可直接使用%systemroot%syswow64 egedit进行编辑)

如何检测 x64 Windows 上是不是安装了 32 位 Java,仅查看文件系统和注册表?

为啥我不能在 64 位机器上正确读取 HKCU 中的 32 位注册表值?

64位 regsrv win10_Regsvr32 在64位机器上的用法

64位 regsrv win10_Regsvr32 在64位机器上的用法