用32位应用程序读取64位注册表中的Office key
public class Utility { #region 32位程序读写64注册表 static UIntPtr HKEY_CLASSES_ROOT = (UIntPtr)0x80000000; static UIntPtr HKEY_CURRENT_USER = (UIntPtr)0x80000001; static UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002; static UIntPtr HKEY_USERS = (UIntPtr)0x80000003; static UIntPtr HKEY_CURRENT_CONFIG = (UIntPtr)0x80000005; // 关闭64位(文件系统)的操作转向 [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr); // 开启64位(文件系统)的操作转向 [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr); // 获取操作Key值句柄 [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern uint RegOpenKeyEx(UIntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, out IntPtr phkResult); //关闭注册表转向(禁用特定项的注册表反射) [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern long RegDisableReflectionKey(IntPtr hKey); //使能注册表转向(开启特定项的注册表反射) [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern long RegEnableReflectionKey(IntPtr hKey); //获取Key值(即:Key值句柄所标志的Key对象的值) [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, int lpReserved, out uint lpType, byte[] lpData, ref uint lpcbData); private static UIntPtr TransferKeyName(string keyName) { switch (keyName) { case "HKEY_CLASSES_ROOT": return HKEY_CLASSES_ROOT; case "HKEY_CURRENT_USER": return HKEY_CURRENT_USER; case "HKEY_LOCAL_MACHINE": return HKEY_LOCAL_MACHINE; case "HKEY_USERS": return HKEY_USERS; case "HKEY_CURRENT_CONFIG": return HKEY_CURRENT_CONFIG; } return HKEY_CLASSES_ROOT; } public static string Get64BitRegistryKey(string parentKeyName, string subKeyName, string keyName) { int KEY_QUERY_VALUE = (0x0001); int KEY_WOW64_64KEY = (0x0100); int KEY_ALL_WOW64 = (KEY_QUERY_VALUE | KEY_WOW64_64KEY); try { //将Windows注册表主键名转化成为不带正负号的整形句柄(与平台是32或者64位有关) UIntPtr hKey = TransferKeyName(parentKeyName); //声明将要获取Key值的句柄 IntPtr pHKey = IntPtr.Zero; //记录读取到的Key值 //StringBuilder result = new StringBuilder("".PadLeft(1024)); byte[] ob = new byte[2048]; uint resultSize = 2048; uint lpType = 3; //关闭文件系统转向 IntPtr oldWOW64State = new IntPtr(); if (Wow64DisableWow64FsRedirection(ref oldWOW64State)) { //获得操作Key值的句柄 RegOpenKeyEx(hKey, subKeyName, 0, KEY_ALL_WOW64, out pHKey); //关闭注册表转向(禁止特定项的注册表反射) RegDisableReflectionKey(pHKey); //获取访问的Key值 RegQueryValueEx(pHKey, keyName, 0, out lpType, ob, ref resultSize); //打开注册表转向(开启特定项的注册表反射) RegEnableReflectionKey(pHKey); } //打开文件系统转向 Wow64RevertWow64FsRedirection(oldWOW64State); //返回Key值 string result = DecodeProductKey(ob); return result.Trim(); } catch (Exception ex) { return null; } } public static string DecodeProductKey(byte[] digitalProductId) { const int keyStartIndex = 0x328; const int keyEndIndex = keyStartIndex + 15; // Possible alpha-numeric characters in product key. char[] digits = new char[] { 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R', 'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9', }; // Length of decoded product key const int decodeLength = 29; // Length of decoded product key in byte-form. // Each byte represents 2 chars. const int decodeStringLength = 15; // Array of containing the decoded product key. char[] decodedChars = new char[decodeLength]; // Extract byte 52 to 67 inclusive. ArrayList hexPid = new ArrayList(); for (int i = keyStartIndex; i <= keyEndIndex; i++) { hexPid.Add(digitalProductId[i]); } for (int i = decodeLength - 1; i >= 0; i--) { // Every sixth char is a separator. if ((i + 1) % 6 == 0) { decodedChars[i] = '-'; } else { // Do the actual decoding. int digitMapIndex = 0; for (int j = decodeStringLength - 1; j >= 0; j--) { int byteValue = (digitMapIndex << 8) | (byte)hexPid[j]; hexPid[j] = (byte)(byteValue / 24); digitMapIndex = byteValue % 24; decodedChars[i] = digits[digitMapIndex]; } } } return new string(decodedChars); } #endregion
调用以office 2010 为例:(当然这个类不仅仅可以用来取office的key)
string key =Utility.Get64BitRegistryKey("HKEY_LOCAL_MACHINE",
@"SOFTWARE\Microsoft\Office\14.0\Registration\{91140000-0011-0000-1000-0000000FF1CE}",
"DigitalProductID");
lpType 的可能取值
REG_NONE = 0
REG_SZ = 1 ——>字符串
REG_EXPAND_SZ = 2 ——>可展开式字符串
REG_BINARY = 3 ——>Binary数据
REG_DWORD = 4 ——>长整数
REG_DWORD_BIG_ENDIAN = 5 ——>BIG_ENDIAN长整数
REG_MULTI_SZ = 7 ——>多重字符串
我们可能需要根据返回的lpType的类型 和 resultSize 对通过RegQueryValueEx获取到的注册表Key值进行相应转换。