我的上一篇文章已经阐述了“32位程序和64位程序在64位平台上读\写注册表的区别”,那么接下来将要回答上篇所留下来的一个问题:32位程序如何访问64位系统注册表(即:64位程序所访问的注册表位置)。
我们已经知道:
①:本机模式 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位注册表的示例代码的详细内容。更多信息请关注PHP中文网其他相关文章!

C#和.NET通过不断的更新和优化,适应了新兴技术的需求。1)C#9.0和.NET5引入了记录类型和性能优化。2).NETCore增强了云原生和容器化支持。3)ASP.NETCore与现代Web技术集成。4)ML.NET支持机器学习和人工智能。5)异步编程和最佳实践提升了性能。

c#.netissutableforenterprise-levelapplications withemofrosoftecosystemdueToItsStrongTyping,richlibraries,androbustperraries,androbustperformance.however,itmaynotbeidealfoross-platement forment forment forment forvepentment offependment dovelopment toveloperment toveloperment whenrawspeedsportor whenrawspeedseedpolitical politionalitable,

C#在.NET中的编程过程包括以下步骤:1)编写C#代码,2)编译为中间语言(IL),3)由.NET运行时(CLR)执行。C#在.NET中的优势在于其现代化语法、强大的类型系统和与.NET框架的紧密集成,适用于从桌面应用到Web服务的各种开发场景。

C#是一种现代、面向对象的编程语言,由微软开发并作为.NET框架的一部分。1.C#支持面向对象编程(OOP),包括封装、继承和多态。2.C#中的异步编程通过async和await关键字实现,提高应用的响应性。3.使用LINQ可以简洁地处理数据集合。4.常见错误包括空引用异常和索引超出范围异常,调试技巧包括使用调试器和异常处理。5.性能优化包括使用StringBuilder和避免不必要的装箱和拆箱。

C#.NET应用的测试策略包括单元测试、集成测试和端到端测试。1.单元测试确保代码的最小单元独立工作,使用MSTest、NUnit或xUnit框架。2.集成测试验证多个单元组合的功能,常用模拟数据和外部服务。3.端到端测试模拟用户完整操作流程,通常使用Selenium进行自动化测试。

C#高级开发者面试需要掌握异步编程、LINQ、.NET框架内部工作原理等核心知识。1.异步编程通过async和await简化操作,提升应用响应性。2.LINQ以SQL风格操作数据,需注意性能。3..NET框架的CLR管理内存,垃圾回收需谨慎使用。

C#.NET面试问题和答案包括基础知识、核心概念和高级用法。1)基础知识:C#是微软开发的面向对象语言,主要用于.NET框架。2)核心概念:委托和事件允许动态绑定方法,LINQ提供强大查询功能。3)高级用法:异步编程提高响应性,表达式树用于动态代码构建。

C#.NET是构建微服务的热门选择,因为其生态系统强大且支持丰富。1)使用ASP.NETCore创建RESTfulAPI,处理订单创建和查询。2)利用gRPC实现微服务间的高效通信,定义和实现订单服务。3)通过Docker容器化微服务,简化部署和管理。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

记事本++7.3.1
好用且免费的代码编辑器