Windows 7 为什么在64位Win7上RegOpenKey()返回错误2

Windows 7 为什么在64位Win7上RegOpenKey()返回错误2,windows-7,vb6,wow64,Windows 7,Vb6,Wow64,我读过这篇文章,它似乎与我要问的是重复的,但我实际上是在问为什么我在两台不同的Win7 64位计算机上看到不同的WOW6432节点行为 我的VB6 32位应用程序正在尝试读取位于的注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Classes\SigToolESI.SigToolESIDevice2016 HideCaptureWindow = N 使用调用RegOpenKey()。此注册表项由使用Wise InstallBuilder 8.12构建的32位应用程序安装程序放

我读过这篇文章,它似乎与我要问的是重复的,但我实际上是在问为什么我在两台不同的Win7 64位计算机上看到不同的WOW6432节点行为

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

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\SigToolESI.SigToolESIDevice2016 HideCaptureWindow = N
使用调用RegOpenKey()。此注册表项由使用Wise InstallBuilder 8.12构建的32位应用程序安装程序放在那里。 在我的64位Win7开发系统上,它运行良好。在客户端的64位Win7计算机上,应用程序出现错误2“未找到”。该客户端还安装在运行XP的32位计算机上,在那里工作正常。我理解,必须发生的是,应用程序正在请求从非Wow6432Node读取,但在那里找不到密钥,因为密钥正在重定向到Wow6432Node

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\SigToolESI.SigToolESIDevice2016 HideCaptureWindow = 
因为当客户端使用Regedit非Wow6432Node注册表项中查找时,它们会找到所需的项,但在Wow6432Node位置找不到它。我不明白的是,如果应用程序和安装程序都是32位程序,为什么它们不从WOW6432节点写入和读取?如果我们都运行同一个安装程序,并且都安装了64位Windows,为什么它在我的开发计算机上的行为是单向的,在客户端上的行为是不同的

我读过这篇文章,但我读到的内容似乎与我观察到的32位应用程序重定向不符。从我在链接中读到的内容来看,32位安装程序和我的32位应用程序似乎都应该将它们的注册表项读写到Wow6432Node。但我观察到的是,在我的64位Win7开发系统上,安装程序写入非Wow6432Node,应用程序读取非Wow6432Node(成功)在客户端的64位Win7系统上,32位安装程序写入非Wow6432Node,但32位应用程序从Wow6432Node读取,并失败

以下是我的Win7开发系统上WOW6432节点和非Wow部分中的类的Regedit视图

更新8-4-2017我让客户端使用regedit在Wow6432Node部分手动创建密钥条目,以尝试确认这是Wow6432Node问题

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\SigToolESI.SigToolESIDevice2016 HideCaptureWindow = N
结果他也犯了同样的错误。因此,也许我的前提是客户端系统试图读取Wow3264Node部分还有什么可能导致错误2?在他的64位Win7系统上出现故障,但在32位XP上没有出现故障,这显然令人怀疑

下面是失败的VB代码。请注意,在指定值名HideCaptureWindow之前,尝试打开SigToolesDevice2016键时会发生错误。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
使用strPath=“SOFTWARE\\Classes\\SigToolESI.SigToolESIDevice2016”调用 strValue=“HideCaptureWindow” 私有函数RegKeyGetString(hBaseKey为长,strPath为字符串,strValue为字符串) Dim hKey 暗淡的状态 “打开钥匙 status=RegOpenKey(hBaseKey、strPath、hKey) 如果状态为0,则 MsgBox(“RegOpenKey”(&hBaseKey&)、&strPath&、&strValue_ &“”=“”&状态) RegKeyGetString=“” 退出功能 如果结束 '获取密钥的内容 RegKeyGetString=RegQueryStringValue(hKey,标准值) "关上钥匙, 雷克洛斯基酒店 端函数
事实证明,这与WOW64完全无关,而是由于特定的客户端没有对注册表项的写访问权限,而代码在尝试读取注册表项时请求“完全访问权限”。非扩展RegOpenKey()假定完全访问,而不是只读 这是代码更改

-    '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)

请注意,这比您意识到的要复杂得多。在Windows 7及更高版本上,类密钥是共享的,即没有单独的32位和64位视图。在早期版本中是这样的。另见。因此,您的计算机运行正常,但客户端的计算机运行不正常。如果您能够重现问题或在客户端的计算机上执行故障排除,则可从MS网站获取Process Monitor作为故障排除工具。我的第一个猜测是,这与它是一个VB6应用程序这一事实有关,例如,Windows可能已经决定应用一些破坏性的兼容性修复程序。(或者可能是您的开发计算机上安装了兼容性修复程序,这是它正常工作的唯一原因。)尝试使用RegQueryReflectionKey()确定两台不同计算机上的反射是否存在差异。不幸的是,我无法轻松访问客户端的Win7系统。查看我的Win7开发系统,我发现在HKEY\U LOCAL\U MACHINE\SOFTWARE\Wow6432Node\Classes\下大约有20个条目,在LOCAL\U MACHINE\SOFTWARE\Classes\下大约有10000个条目。我的特定类SigToolESIDevice2016不在WOW6432节点\类中。如果共享了Classes键,为什么我会看到SOFTWARE\Wow6432Node\Classes的类列表与SOFTWARE\Classes的类列表不同?请参见原始问题中添加的Regedit的WOW和非WOW视图截屏–Jonsee。我不认为这是你的问题,但这可能值得知道。关于Wow6432Node\类中存在某些键的原因,我的最佳猜测是向后兼容,例如,可能有一些最初为Windows Vista编写的程序或软件库,直接从Wow6432Node读取这些特定项,如果找不到,则会中断。