64位系统下32位C#程序如何修改目标64位注册表项?
解决64位机器上32位C#程序修改64位注册表项的问题
这个问题我碰到过好多次啦,本质是Windows的注册表重定向器在搞怪:32位程序访问HKLM\Software时,系统会自动把请求转去HKLM\Software\Wow6432Node,目的是隔离32位和64位程序的注册表数据。要直接修改64位的目标注册表项,有两种实用方法:
方法一:用RegistryView枚举(推荐,.NET Framework 4及以上可用)
你可以通过RegistryKey.OpenBaseKey明确指定访问64位注册表视图,这样就能绕过重定向直接操作目标分支。修改后的代码如下:
using Microsoft.Win32; string path = @"Software\Microsoft\Windows NT\CurrentVersion\Windows"; // 打开64位的LocalMachine根项 RegistryKey localMachine64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64); // 打开目标子项并开启可写权限 RegistryKey myKey = localMachine64.OpenSubKey(path, true); if (myKey != null) { myKey.SetValue("USERProcessHandleQuota", 50000, RegistryValueKind.DWord); myKey.Close(); } localMachine64.Close();
⚠️ 注意:这段代码必须以管理员权限运行,毕竟修改HKLM下的注册表项需要系统级权限,不然会抛出权限不足的异常哦。
方法二:P/Invoke调用Win32 API(兼容旧版.NET)
如果你的程序基于.NET Framework 4以下版本,不支持RegistryView,那可以通过P/Invoke调用RegOpenKeyEx函数,传入KEY_WOW64_64KEY(0x0100)标志来绕过重定向。示例代码如下:
using System; using System.Runtime.InteropServices; class RegistryHelper { private const int KEY_WOW64_64KEY = 0x0100; private const int KEY_WRITE = 0x20006; private const int REG_DWORD = 4; [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int RegOpenKeyEx(IntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, out IntPtr phkResult); [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int RegSetValueEx(IntPtr hKey, string lpValueName, uint Reserved, uint dwType, byte[] lpData, int cbData); [DllImport("advapi32.dll", SetLastError = true)] private static extern int RegCloseKey(IntPtr hKey); public static void Set64BitHandleQuota() { IntPtr hLocalMachine = new IntPtr(-2147483646); // HKEY_LOCAL_MACHINE的固定句柄值 IntPtr hSubKey; int openResult = RegOpenKeyEx(hLocalMachine, @"Software\Microsoft\Windows NT\CurrentVersion\Windows", 0, KEY_WRITE | KEY_WOW64_64KEY, out hSubKey); if (openResult == 0) // 成功打开子项 { int quotaValue = 50000; byte[] valueData = BitConverter.GetBytes(quotaValue); RegSetValueEx(hSubKey, "USERProcessHandleQuota", 0, REG_DWORD, valueData, valueData.Length); RegCloseKey(hSubKey); } } }
同样,这个方法也需要管理员权限才能执行成功,而且记得要处理可能出现的异常(比如路径不存在、权限不够等),让程序更稳定。
内容的提问来源于stack exchange,提问作者mehta ankit
相关产品推荐
相关产品推荐

