【问题标题】:Why RegOpenKey() returning error 2 on 64 bit Win7为什么 RegOpenKey() 在 64 位 Win7 上返回错误 2
【发布时间】:2017-08-03 23:33:19
【问题描述】:

我已阅读此Question,这似乎与我所问的内容重复,但我实际上是在问为什么我在两台不同的 Win7 64 位计算机上看到不同的 Wow6432Node 行为

我的 VB6 32 位应用程序正在尝试读取注册表项

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\SigToolESI.SigToolESIDevice2016 HideCaptureWindow = N

使用调用 RegOpenKey()。此注册表项由使用 Wise InstallBuilder 8.12 构建的应用程序 32 位安装程序放置在那里。 在我的 64 位 Win7 开发系统上它工作正常。在客户端的 64 位 Win7 计算机上,应用程序收到错误 2“未找到”。该客户端还安装在运行 XP 的 32 位计算机上,并且在那里运行良好。我知道必须发生的事情是应用程序请求从 non-Wow6432Node 读取并且没有在那里找到密钥,因为密钥被重定向到 Wow6432Node

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\SigToolESI.SigToolESIDevice2016 HideCaptureWindow = 

因为当客户端使用 Regedit 查看 non-Wow6432Node 注册表项时,他们找到了预期的密钥,但在 Wow6432Node 位置。我不明白的是,如果应用程序和安装程序都是 32 位程序,为什么它们不都从 Wow6432Node 读写?如果我们都运行相同的安装程序并且都安装了 64 位 Windows,为什么它在我的开发计算机上的行为是一种方式而在客户端上的行为却不同?

我已阅读此link,但我阅读的内容似乎与我观察到的 32 位应用程序重定向不匹配。从我在链接中读到的内容看来,32 位安装程序和我的 32 位应用程序都应该在 Wow6432Node 中读取和写入它们的注册表项。但我观察到的是,在我的 64 位 Win7 开发系统上,安装程序写入 non-Wow6432Node 并且应用程序从 non-Wow6432Node 读取(成功)在客户端的 64 位Win7 系统 32 位安装程序写入 non-Wow6432Node 但 32 位应用程序从 Wow6432Node 读取并失败。

这是我的 Win7 开发系统上 Wow6432Node 和 Non-Wow 部分的 Regedit 中的视图

SOFTWARE\Wow6432Node\Classes

SOFTWARE\Classes

2017 年 8 月 4 日更新我让客户端使用 regedit 手动为 Wow6432Node 部分中的密钥创建一个条目,以尝试确认这是 Wow6432Node 问题。

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\SigToolESI.SigToolESIDevice2016 HideCaptureWindow = N

结果他得到了同样的错误。所以也许我的前提是客户端系统正在尝试读取 Wow3264Node 部分。 还有什么可能导致错误 2? 显然它在他的 64 位 Win7 系统上失败但在 32 位 XP 上失败了。

这是失败的 VB 代码。请注意,在指定值名称 HideCaptureWindow 之前尝试打开 SigToolESIDevice2016 键时会发生错误。 SigToolESIDevice2016 密钥是通过注册 ActiveX VB 组件创建的,而不是像我之前在安装程序添加 HideCaptureWindow 值时所说的那样:

Called with strPath="SOFTWARE\\Classes\\SigToolESI.SigToolESIDevice2016"
            strValue="HideCaptureWindow"

    Private Function RegKeyGetString(hBaseKey As Long, strPath As String, strValue As String)
        Dim hKey
        Dim status As Long

        'Open the key
        status = RegOpenKey(hBaseKey, strPath, hKey)

        If status <> 0 Then
            MsgBox ("RegOpenKey(" & hBaseKey & ", """ & strPath & """, """ & strValue _
            & """) = " & status)
            RegKeyGetString = ""
            Exit Function
        End If

        'Get the key's content
        RegKeyGetString = RegQueryStringValue(hKey, strValue)

        'Close the key
        RegCloseKey hKey
    End Function

【问题讨论】:

  • 请注意,这比您想象的要复杂。在 Windows 7 和更高版本上,Classes 键是共享的,即没有单独的 32 位和 64 位视图。在早期版本中,它是reflected。另见Registry Keys Affected by WOW64。所以你的机器的行为符合预期,但客户端的机器不是。
  • 进程监视器,可从 MS 网站获得,如果您能够重现问题或在客户端计算机上进行故障排除,它可能作为故障排除工具很有用。我的第一个猜测是,这与它是一个 VB6 应用程序这一事实有关,例如,Windows 可能已经决定应用一些破坏性的兼容性修复程序。 (或者,您的开发机器上可能已经安装了兼容性修复程序,这也是它能够正常工作的唯一原因。)
  • 尝试使用 RegQueryReflectionKey() 确定两台不同机器上的反射是否存在差异。
  • 很遗憾,我无法轻松访问客户的 Win7 系统。查看我的 Win7 开发系统,我看到 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\ 下大约有 20 个条目,LOCAL_MACHINE\SOFTWARE\Classes\ 下大约有 10,000 个条目。而我的特定类 SigToolESIDevice2016 不在 Wow6432Node\Classes 中。如果共享 Classes 密钥,为什么我看到 SOFTWARE\Wow6432Node\Classes 的 Classes 列表与 SOFTWARE\Classes 不同?查看来自 Regedit 的 WOW 和非 WOW 视图的屏幕截图添加到原始问题 - JonN
  • 另见registry virtualization。我不认为这可能是你的问题,但它可能值得知道。关于为什么 Wow6432Node\Classes 中存在某些键,我最好的猜测是向后兼容性,例如,也许有一些最初为 Windows Vista 编写的程序或软件库直接从 Wow6432Node 读取这些特定条目,如果找不到它们就会中断。

标签: windows-7 vb6 wow64


【解决方案1】:

事实证明,这根本与 WOW64 无关,而是由于特定客户端没有对注册表项的写入权限以及在尝试读取注册表项时请求“完全访问”的代码造成的。非扩展 RegOpenKey() 假定完全访问而不是 READ_ONLY 这是代码更改。

-    'Open the key
-10  status = RegOpenKey(hBaseKey, strPath, hKey)

+    ' Open the key for READ ONLY accesss Some clients were getting
+    ' access error on this call when RegOpenKey() was used which
+    ' requests full access instead of RegOpenKeyEx() with READ ONLY
+    ' access.
+10  status = RegOpenKeyEx(hBaseKey, strPath, 0, KEY_READ, hKey)

【讨论】:

    猜你喜欢
    • 2010-09-20
    • 2012-08-28
    • 1970-01-01
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 1970-01-01
    相关资源
    最近更新 更多