有一个读取注册表信息的程序 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, subkeystring , 0, KEY_READ, &hKey) == ERROR_SUCCESS)/
,在32位下完全正常,但是在64位返回值正确,但就是读不到东西。后来单步发现读不到东西,就搜64位读注册表失败,发现需要加
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, subkeystring , 0,KEY_READ|KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)就可以了,我是全部把权限提高,还可以根据不同的操作系统,设置不同的参数。
IsWow64Process 判断64位操作系统
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process;
IsWow64返回TRUE则是64位系统,否则为32位系统。
BOOL IsWow64()
{
BOOL bIsWow64 = FALSE;
fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
if(NULL != fnIsWow64Process)
{
if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
{
return FALSE;
}
}
return bIsWow64;
}
可参考的文献:
http://msdn.microsoft.com/en-us/library/aa384129(v=VS.85).aspx
http://www.codeproject.com/Articles/51326/Net-Compilation-registry-accessing-and-applicatio
http://boluns.blog.163.com/blog/static/69845968201071132032313/
The code
The next code is a personal translation to C# of several pieces of code I found, mostly from here:
![](https://www.codeproject.com/images/arrow-up-16.png)
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegOpenKeyEx")]
static extern int RegOpenKeyEx(IntPtr hKey, string subKey, uint options, int sam,
out IntPtr phkResult);
[Flags]
public enum eRegWow64Options : int
{
None = 0x0000,
KEY_WOW64_64KEY = 0x0100,
KEY_WOW64_32KEY = 0x0200,
// Add here any others needed, from the table of the previous chapter
}
[Flags]
public enum eRegistryRights : int
{
ReadKey = 131097,
WriteKey = 131078,
}
public static RegistryKey OpenSubKey(RegistryKey pParentKey, string pSubKeyName,
bool pWriteable,
eRegWow64Options pOptions)
{
if (pParentKey == null || GetRegistryKeyHandle(pParentKey).Equals(System.IntPtr.Zero))
throw new System.Exception("OpenSubKey: Parent key is not open");
eRegistryRights Rights = eRegistryRights.ReadKey;
if (pWriteable)
Rights = eRegistryRights.WriteKey;
System.IntPtr SubKeyHandle;
System.Int32 Result = RegOpenKeyEx(GetRegistryKeyHandle(pParentKey), pSubKeyName, 0,
(int)Rights | (int)pOptions, out SubKeyHandle);
if (Result != 0)
{
System.ComponentModel.Win32Exception W32ex =
new System.ComponentModel.Win32Exception();
throw new System.Exception("OpenSubKey: Exception encountered opening key",
W32ex);
}
return PointerToRegistryKey(SubKeyHandle, pWriteable, false);
}
private static System.IntPtr GetRegistryKeyHandle(RegistryKey pRegisteryKey)
{
Type Type = Type.GetType("Microsoft.Win32.RegistryKey");
FieldInfo Info = Type.GetField("hkey", BindingFlags.NonPublic | BindingFlags.Instance);
SafeHandle Handle = (SafeHandle)Info.GetValue(pRegisteryKey);
IntPtr RealHandle = Handle.DangerousGetHandle();
return Handle.DangerousGetHandle();
}
private static RegistryKey PointerToRegistryKey(IntPtr hKey, bool pWritable,
bool pOwnsHandle)
{
// Create a SafeHandles.SafeRegistryHandle from this pointer - this is a private class
BindingFlags privateConstructors = BindingFlags.Instance | BindingFlags.NonPublic;
Type safeRegistryHandleType = typeof(
SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType(
"Microsoft.Win32.SafeHandles.SafeRegistryHandle");
Type[] safeRegistryHandleConstructorTypes = new Type[] { typeof(System.IntPtr),
typeof(System.Boolean) };
ConstructorInfo safeRegistryHandleConstructor =
safeRegistryHandleType.GetConstructor(privateConstructors,
null, safeRegistryHandleConstructorTypes, null);
Object safeHandle = safeRegistryHandleConstructor.Invoke(new Object[] { hKey,
pOwnsHandle });
// Create a new Registry key using the private constructor using the
// safeHandle - this should then behave like
// a .NET natively opened handle and disposed of correctly
Type registryKeyType = typeof(Microsoft.Win32.RegistryKey);
Type[] registryKeyConstructorTypes = new Type[] { safeRegistryHandleType,
typeof(Boolean) };
ConstructorInfo registryKeyConstructor =
registryKeyType.GetConstructor(privateConstructors, null,
registryKeyConstructorTypes, null);
RegistryKey result = (RegistryKey)registryKeyConstructor.Invoke(new Object[] {
safeHandle, pWritable });
return result;
}
How to use the Code
The OpenSubKey will return the searched key, allowing you to specify reading from the normal registry, or from the alternative 32-bit, WOW64 registry. The following example reads from the 32-bit WOW64 registry:
try
{
RegistryKey key = OpenSubKey(Registry.LocalMachine,"Software\[Key]",false,
eRegWow64Options.KEY_WOW64_32KEY);
}
catch
{
// Parent key not open, exception found at opening (probably related to
// security permissions requested)
}
You just need to place your key name where “[Key]” is.