不要滥用 KEY_WOW64_64KEY

在 64-bit OS 开发过注册表的人都应该知道, 其访问存在 redirect. 

我曾经开发过一个注册表程序, 涉及到会在 64-bit Windows 下运行, 翻看 MSDN 有一句话是这样说的: 看加红字体

KEY_WOW64_32KEY (0x0200)

Indicates that an application on 64-bit Windows should operate on the 32-bit registry view. This flag is ignored by 32-bit Windows. For more information, see Accessing an Alternate Registry View.

This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.

Windows 2000:  This flag is not supported.

KEY_WOW64_64KEY (0x0100)

Indicates that an application on 64-bit Windows should operate on the 64-bit registry view. This flag is ignored by 32-bit Windows. For more information, see Accessing an Alternate Registry View.

This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.

Windows 2000:  This flag is not supported.

 

我发挥了程序员最擅长的归纳联想能力, 并想出来一个 "完美" 的解决方法: 既然 32-bit OS 会忽略KEY_WOW64_64KEY 和 KEY_WOW64_32KEY 标志位, 那么在所有程序中使用 KEY_WOW64_64KEY 这个标志. 即使程序运行在 32-bit OS 上, 有这个标志位也不会有什么作用. 然而到了 64-bit OS 中, 我企图完全通过 key 的路径来控制程序了. 于是我是这样做的:

LONG rtn = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Wow6432Node\\Microsoft\\Office", 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey);

上述代码在 Win 7 x64 下工作正常, 我以为我找到了全解.

 

就在我得意的时候, Tester 告诉我 Vista x64 上程序运行有问题. 问题很快被确定为注册表读取失败, 但是为何失败却不知道, 系统返回了无法找到该键的错误代码 2. 我仔细查看注册表, 反复对比反复尝试, 还是失败. 我开始怀疑虚拟机会不会有什么特殊的影响, 抱着对程序的自信, 我竟然在虚拟机的 Vista x64 上安装了 vs 2010! 一步一步调试, 最后发现 RegOpenKeyEx() 这里确实是失败了. 我反复思考, 突然想起一片博客上看到了一句话: Never handle "Wow6432Node" yourself. 其原文链接我已经找不到了.

 

抱着尝试, 我修改了代码:

REGSAM flag = KEY_WOW64_32KEY or KEY_WOW64_64KEY;       // 伪代码
LONG rtn = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Wow6432Node\\Microsoft\\Office", 0, KEY_ALL_ACCESS | flag, &hKey);


这次在 Vista x64 和 Win 7 x64 下工作正常. 

 

总结起来就是一句话: 使用标志位 KEY_WOW64_32KEY  KEY_WOW64_64KEY 来控制 HKEY_LOCAL_MACHINE\Software 的访问, 如果你的程序可能会运行在 x64 Windows 上.

 

另:

一位网友(感谢 Tttavg)好心提醒, msdn 明确说明了两者不能共存, msdn 说明如下: http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129(v=vs.85).aspx

"

Either KEY_WOW64_32KEY or KEY_WOW64_64KEY can be specified. If both flags are specified, the function fails with ERROR_INVALID_PARAMETER.
  Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: If both flags are specified, the function’s behavior is undefined.

"

posted @ 2012-01-03 16:20  walfud  阅读(14422)  评论(11编辑  收藏  举报