Accessing 64 bit registry from 32 bit application

2019-02-11 22:27发布

问题:

I need to open a registry entry "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{26A24AE4-039D-4CA4-87B4-2F86416024FF}" in c++. It contains the java 64 bit application. The full path of that registry entry is "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{26A24AE4-039D-4CA4-87B4-2F86416024FF}".

We can view this path through regedit. I use

returnStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
    TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{26A24AE4-039D-4CA4-87B4-2F86416024FF}"),
    0, KEY_ALL_ACCESS, &hKey)

for open the registry; But it returns error value (2).

returnStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall")...

returns a success result. What can i do?

回答1:

The registry keys for 32 bit and 64 applications are separated, you can't access (directly) the 64 bit registry from your 32 bit application. In your case the required hive doesn't exist in the 32 bit part of the registry then you can access the parent folder only.

From MSDN:

On 64-bit Windows, portions of the registry entries are stored separately for 32-bit application and 64-bit applications and mapped into separate logical registry views using the registry redirector and registry reflection, because the 64-bit version of an application may use different registry keys and values than the 32-bit version. There are also shared registry keys that are not redirected or reflected.

You can read the list on MSDN: Registry Keys Affected by WOW64. Unfortunately the SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall is not mentioned but it's affected too.

Solution
What you have to do is to explicitly ask RegOpenKeyEx to access the 64 bit part of the registry. This can be done adding the KEY_WOW64_64KEY flag to your call (you can access the 32 bit registry from a 64 bit application using KEY_WOW64_32KEY). Please note that this flag is not supported on Windows 2000 then if your application must be compatible with that (old) version you have to manage the case.

See this link on MSDN for further details: Accessing an Alternate Registry View.

To make it easy, simply change your call from:

returnStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
    TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{26A24AE4-039D-4CA4-87B4-2F86416024FF}"),
    0, KEY_ALL_ACCESS, &hKey);

to:

returnStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
    TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{26A24AE4-039D-4CA4-87B4-2F86416024FF}"),
    0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey);

Note
Note that you may access the key only via its path without any flags using this HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall. Because the Wow6432 node is the virtualized node used by WOW64 but you shouldn't rely on this, it's stable but it should be considered an implementation detail subject to change.

References
- Registry Virtualization on MSDN.
- Readers my find interesting tips on this post: http://poshcode.org/2470, it's for the PowerShell but it explains how to access WMI data (relative to the 64 bit registry part) from a 32 bit application.



回答2:

Error 2 means the registry path does not exist.

Make sure that the key {26A24AE4-039D-4CA4-87B4-2F86416024FF} actually exists under SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall