我们已晓得:
①:本机形式 64 位顺序运转在纯形式下,而且接见键和存储在以下注册表子键中的值:HKEY_LOCAL_MACHINE\Software
②:32 位顺序运转在 WOW64 形式下,而且接见键和值存储在以下注册表子项中:HKEY_LOCAL_MACHINE\Software\WOW6432nod
那末要完成32为顺序接见64位注册表信息,还要晓得以下观点:1:文件体系转向。2:注册表重定向(转向)。3:注册表反射。
①:文件体系转向
32 位历程不能加载64位Dll,64位历程也不能够加载32位Dll。Windows的体系目次包含了一切装置的应用顺序和它们的Dll文件,依据我们所述 的划定规矩,
它应该被分为给64位应用顺序的目次和给32位应用顺序的目次。假如不如许,我们就没法辨别32位和64位的Dll文件。关于64位应用顺序,其 文件一般被
放在%windir%\system32和%programfiles%(比方:c:\program files)。关于32位应用顺序,其文件一般在%windir%\syswow64和
C:\program files (x86)下面。假如我们用32位顺序去接见%windir%\system32,不论我们用硬编码照样别的的体式格局,体系都邑自动地给我们
转向到%windir%\syswow64下面。这类转向关于每一个32位应用顺序默许都是翻开的。然则这类转向关于我们来讲并不老是须要的。那末我们能够在
C#内里挪用相干的API来封闭和翻开这类转向。经常运用的函数有3个:
Wow64DisableWow64FsRedirection(封闭体系转 向),
Wow64RevertWow64FsRedirection(翻开体系转向),
Wow64EnableWow64FsRedirection(打 开体系转向)。
然则Wow64EnableWow64FsRedirection在嵌套运用的时刻不可靠,所以通经常运用上面的 Wow64RevertWow64FsRedirection来翻开文件体系转向
功用。在C#中,我们能够应用DllImport直接挪用这两个函数。
②:注册表重定向(转向)
若要支撑的 32 位和 64 位 COM 注册和顺序共存状况,WOW64 子体系供应 32 位顺序运用的注册表的另一个视图。在 WOW64 子体系运用注册表
重定向截获位级别的注册表挪用。注册表重定向还能够确保注册表挪用被定向到在注册表中准确的分支。
当我们装置新顺序或 Windows x64 版的盘算机上运转顺序时,所做的 64 位顺序的注册表挪用接见 HKEY_LOCAL_MACHINE\Software 注册表子键
不重定向。WOW64 截获由 32 位顺序的注册表挪用到 HKEY_LOCAL_MACHINE\Software,然后将它们重定向到
HKEY_LOCAL_MACHINE\Software\WOW6432node 子键。 经由历程重定向仅 32 位顺序挪用,WOW64 可确保顺序一直写入响应的注册表子键。
注册表重定向不请求顺序代码修正,和此历程是对用户通明。
③:注册表反射
反射使两个雷同的注册表,以支撑同时举行的本机和 WOW64 操纵的物理副本的存在,
翻开注册表的 64 位节在一切时间和注册表反射供应了一种包容 32 位的及时要领。
简朴的了解了这些,下面说一下细致的完成步骤:
封闭64位(文件体系)的操纵转向
取得操纵Key值的句柄
封闭注册表转向(制止特定项的注册表反射)
猎取接见的Key值
翻开注册表转向(开启特定项的注册表反射)
开启64位(文件体系)的操纵转向
【注:因为我们在顺序中用了DllImport,所以要引入定名空间:System.Runtime.InteropServices】
下面请看代码示例
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Microsoft.Win32; 6 using System.Runtime.InteropServices; 7 8 namespace OperateRegistrationTable 9 { 10 class Programe 11 { 12 static void Main(string[] args) 13 { 14 string myParentKeyName = "HKEY_LOCAL_MACHINE"; 15 string mySubKeyName = @"SOFTWARE\EricSun\MyTestKey"; 16 string myKeyName = "MyKeyName"; 17 18 string value = string.Empty; 19 value = Utility.Get64BitRegistryKey(myParentKeyName, mySubKeyName, myKeyName); 20 Console.WriteLine("The Value is: {0}", value); 21 } 22 } 23 24 public class Utility 25 { 26 #region 32位顺序读写64注册表 27 28 static UIntPtr HKEY_CLASSES_ROOT = (UIntPtr)0x80000000; 29 static UIntPtr HKEY_CURRENT_USER = (UIntPtr)0x80000001; 30 static UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002; 31 static UIntPtr HKEY_USERS = (UIntPtr)0x80000003; 32 static UIntPtr HKEY_CURRENT_CONFIG = (UIntPtr)0x80000005; 33 34 // 封闭64位(文件体系)的操纵转向 35 [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 36 public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr); 37 // 开启64位(文件体系)的操纵转向 38 [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 39 public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr); 40 41 // 猎取操纵Key值句柄 42 [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 43 public static extern uint RegOpenKeyEx(UIntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, out IntPtr phkResult); 44 //封闭注册表转向(禁用特定项的注册表反射) 45 [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 46 public static extern long RegDisableReflectionKey(IntPtr hKey); 47 //使能注册表转向(开启特定项的注册表反射) 48 [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 49 public static extern long RegEnableReflectionKey(IntPtr hKey); 50 //猎取Key值(即:Key值句柄所标志的Key对象的值) 51 [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 52 private static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, int lpReserved, 53 out uint lpType, System.Text.StringBuilder lpData, 54 ref uint lpcbData); 55 56 private static UIntPtr TransferKeyName(string keyName) 57 { 58 switch (keyName) 59 { 60 case "HKEY_CLASSES_ROOT": 61 return HKEY_CLASSES_ROOT; 62 case "HKEY_CURRENT_USER": 63 return HKEY_CURRENT_USER; 64 case "HKEY_LOCAL_MACHINE": 65 return HKEY_LOCAL_MACHINE; 66 case "HKEY_USERS": 67 return HKEY_USERS; 68 case "HKEY_CURRENT_CONFIG": 69 return HKEY_CURRENT_CONFIG; 70 } 71 72 return HKEY_CLASSES_ROOT; 73 } 74 75 public static string Get64BitRegistryKey(string parentKeyName, string subKeyName, string keyName) 76 { 77 int KEY_QUERY_VALUE = (0x0001); 78 int KEY_WOW64_64KEY = (0x0100); 79 int KEY_ALL_WOW64 = (KEY_QUERY_VALUE | KEY_WOW64_64KEY); 80 81 try 82 { 83 //将Windows注册表主键名转化成为不带正负号的整形句柄(与平台是32或许64位有关) 84 UIntPtr hKey = TransferKeyName(parentKeyName); 85 86 //声明将要猎取Key值的句柄 87 IntPtr pHKey = IntPtr.Zero; 88 89 //纪录读取到的Key值 90 StringBuilder result = new StringBuilder("".PadLeft(1024)); 91 uint resultSize = 1024; 92 uint lpType = 0; 93 94 //封闭文件体系转向 95 IntPtr oldWOW64State = new IntPtr(); 96 if (Wow64DisableWow64FsRedirection(ref oldWOW64State)) 97 { 98 //取得操纵Key值的句柄 99 RegOpenKeyEx(hKey, subKeyName, 0, KEY_ALL_WOW64, out pHKey); 100 101 //封闭注册表转向(制止特定项的注册表反射) 102 RegDisableReflectionKey(pHKey); 103 104 //猎取接见的Key值 105 RegQueryValueEx(pHKey, keyName, 0, out lpType, result, ref resultSize); 106 107 //翻开注册表转向(开启特定项的注册表反射) 108 RegEnableReflectionKey(pHKey); 109 } 110 111 //翻开文件体系转向 112 Wow64RevertWow64FsRedirection(oldWOW64State); 113 114 //返回Key值 115 return result.ToString().Trim(); 116 } 117 catch (Exception ex) 118 { 119 return null; 120 } 121 } 122 123 #endregion 124 } 125 }
Get64BitRegistryKey函数的三个参数离别代表:主键名(如:HKEY_LOCAL_MACHINE等),子键名,Key名,返回的是Key的Value(64位体系注册表的键值),经由历程上面的要领就完全能够完成用32顺序接见64位体系注册表(即:64位顺序所接见的注册表位置)。
以上就是C# 32位顺序接见64位注册表的示例代码的细致内容,更多请关注ki4网别的相干文章!