8 January, 2010
0 Comments
0 categories
Well in .NET 4.0 this will all change, but for know it you want to read a key from the registry and you don’t know if it’s in the 32 bits part of the registry or in the 64 bit part and you don’t know if you’re application will be compiled as x86 or x64 en you don’t know on which machine it will be deployed (x86 or x64). In fact you don´t know anything, you can use the GetRegistryKeyHandle function to try to find the key in the 64 bit part and then if not found try the find the key in the 32 bits part of the registry:
public static UIntPtr HKEY_CURRENT_USER = (UIntPtr)0x80000001; public static UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002; public static int KEY_QUERY_VALUE = 0x0001; public static int KEY_READ = 0x20019; public static int KEY_SET_VALUE = 0x0002; public static int KEY_CREATE_SUB_KEY = 0x0004; public static int KEY_ENUMERATE_SUB_KEYS = 0x0008; public static int KEY_WOW64_64KEY = 0x0100; public static int KEY_WOW64_32KEY = 0x0200; public const int Success = 0; public const int FileNotFound = 2; public const int AccessDenied = 5; public const int InvalidParameter = 87; public const int MoreData = 234; public const int NoMoreEntries = 259; public const int MarkedForDeletion = 1018; public const int BufferMaxLength = 2048; [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegOpenKeyExW", SetLastError = true)] public static extern int RegOpenKeyExW(UIntPtr hKey, string subKey, uint options, int sam, out UIntPtr phkResult); [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegEnumKeyW")] private static extern int RegEnumKeyW(UIntPtr keyBase, int index, StringBuilder nameBuffer, int bufferLength);
/// <summary> ///Try to find the regsitrykey in the 64 bit part of the registry. ///If not found, try to find the registrykey in the 32 bit part of the registry. /// </summary> /// <param name="regKeyPath"></param> /// <returns>A registrykeyhandle</returns> public UIntPtr GetRegistryKeyHandle(stringregKeyPath) { UIntPtr regKeyHandle; // Check parameters if(string.IsNullOrEmpty(regKeyPath)) { throw newArgumentNullException("regKeyPath", "GetRegistryKeyHandle: regKeyPath is null or empty."); } // KEY_WOW64_64KEY // Access a 64-bit key from either a 32-bit or 64-bit application (not supported on Windows 2000). // 64-bit key = all keys in HKEY_LOCAL_MACHINE\Software except the HKEY_LOCAL_MACHINE\Software\Wow6432Node // // Check if the registrykey can be found in the 64 bit registry part of the register if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, regKeyPath, 0, KEY_READ | KEY_WOW64_64KEY, outregKeyHandle) != Success) { // KEY_WOW64_32KEY // Access a 32-bit key from either a 32-bit or 64-bit application. (not supported on Windows 2000) // 32-bit key = all keys in HKEY_LOCAL_MACHINE\Software\Wow6432Node // // Check if the registrykey can be found in the 32 bit registry part of the register if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, regKeyPath, 0, KEY_READ | KEY_WOW64_32KEY, outregKeyHandle) != Success) { throw newApplicationException(string.Format(@"GetRegistryKeyHandle: Could not find regstrykey [{0}\{1}]", Registry.LocalMachine, regKeyPath)); } } return regKeyHandle; }
public void LoopSubKeysTest()
{
UIntPtr regKeyHandle = helper.GetRegistryKeyHandle(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes");
StringBuilder buffer = new StringBuilder(BufferMaxLength); for (int index = 0; true; index++) { int result = RegEnumKeyW(regKeyHandle, index, buffer, buffer.Capacity); if (result == Success) { Console.WriteLine(buffer.ToString()); buffer.Length = 0; continue; } if (result == NoMoreEntries) { break; }; throw new ApplicationException("This RegEnumKeyW result is unknown"); } }
Tags: C#
Thank’s for sharing your knowlege! I have the same problem, I tried your code and it works, but to get the subkeys was not enougth, so I used other article:
http://www.codeproject.com/Articles/51326/Net-Compilation-registry-accessing-and-application.aspx?msg=3426476#xx3426476xx
Thank you.