C#操作注册表
1、微软为了让32位程序不做任何修改就能运行在64的操作系统上,添加了一个十分重要的WOW64子系统来实现这个功能,WOW64是Windows-32-on-Windows-64的简称,从总体上来说,WOW64是一套基于用户模式的动态链接库,它可以把32位应用程序的发出的命令 翻译成64位系统可以接受的格式,即:WOW 层处理诸如在 32 位和 64 位模式之间切换处理器以及模拟 32 位系统的事务。
32位与64位特点的两个重要表现方面为:文件系统与注册表。
文件系统:32位进程不能加载64位Dll,64位进程也不可以加载32位Dll。
注册表:为了防止注册表键冲突,64位机器注册表信息分成了两个部分。一部分是专门给64位系统(即:64位程序)访问的,另一部分是专门给32位系统(即:32位程序)访问的,放在Wow6432Node下面。(Wow6432Node这个节 点存在于 HKEY_LOCAL_MACHINE和HKEY_CURRENT_USER下面)
2、举例说明
首先下载了32位软件Winrar(下载地址:http://www.winrar.com.cn/),分别在32位和64位机器上进行安装,版本号请看截图
通过查询注册表可知,Winrar的版本号在32位机器里的注册表里的路径Path:"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinRAR archiver ".且Key值为:"DisplayVersion"
Winrar的版本号在32位机器里的注册表里的路径Path:"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\WinRAR archiver ".且Key值为:"DisplayVersion"
3、现在编写一个代码分别进行读取,更改,以实现C#读取注册表
写一个注册表类RegUtil.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using Microsoft.Win32; namespace ToolUtils { public static class RegUtil { static readonly IntPtr HKEY_CLASSES_ROOT = new IntPtr(unchecked((int)0x80000000)); static readonly IntPtr HKEY_CURRENT_USER = new IntPtr(unchecked((int)0x80000001)); static readonly IntPtr HKEY_LOCAL_MACHINE = new IntPtr(unchecked((int)0x80000002)); static readonly IntPtr HKEY_USERS = new IntPtr(unchecked((int)0x80000003)); static readonly IntPtr HKEY_PERFORMANCE_DATA = new IntPtr(unchecked((int)0x80000004)); static readonly IntPtr HKEY_CURRENT_CONFIG = new IntPtr(unchecked((int)0x80000005)); static readonly IntPtr HKEY_DYN_DATA = new IntPtr(unchecked((int)0x80000006)); // 获取操作Key值句柄 [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int RegOpenKeyEx(IntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, out IntPtr phkResult); //创建或打开Key值 [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int RegCreateKeyEx(IntPtr hKey, string lpSubKey, int reserved, string type, int dwOptions, int REGSAM, IntPtr lpSecurityAttributes, out IntPtr phkResult, out int lpdwDisposition); //关闭注册表转向(禁用特定项的注册表反射) [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int RegDisableReflectionKey(IntPtr hKey); //使能注册表转向(开启特定项的注册表反射) [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int 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, System.Text.StringBuilder lpData, ref uint lpcbData); //设置Key值 [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int RegSetValueEx(IntPtr hKey, string lpValueName, uint unReserved, uint unType, byte[] lpData, uint dataCount); //关闭Key值 [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int RegCloseKey(IntPtr hKey); public static IntPtr TransferKeyName(string keyName) { IntPtr ret = IntPtr.Zero; switch (keyName) { case "HKEY_CLASSES_ROOT": ret = HKEY_CLASSES_ROOT; break; case "HKEY_CURRENT_USER": ret = HKEY_CURRENT_USER; break; case "HKEY_LOCAL_MACHINE": ret = HKEY_LOCAL_MACHINE; break; case "HKEY_USERS": ret = HKEY_USERS; break; case "HKEY_PERFORMANCE_DATA": ret = HKEY_PERFORMANCE_DATA; break; case "HKEY_CURRENT_CONFIG": ret = HKEY_CURRENT_CONFIG; break; case "HKEY_DYN_DATA": ret = HKEY_DYN_DATA; break; default: ret = HKEY_LOCAL_MACHINE; break; } return ret; } /// <summary> /// 设置64位注册表 /// </summary> /// <param name="key"></param> /// <param name="subKey"></param> /// <param name="name"></param> /// <param name="value"></param> /// <returns></returns> public static int Set64BitRegistryKey(string key, string subKey, string name, string value) { int STANDARD_RIGHTS_ALL = (0x001F0000); int KEY_QUERY_VALUE = (0x0001); int KEY_SET_VALUE = (0x0002); int KEY_CREATE_SUB_KEY = (0x0004); int KEY_ENUMERATE_SUB_KEYS = (0x0008); int KEY_NOTIFY = (0x0010); int KEY_CREATE_LINK = (0x0020); int SYNCHRONIZE = (0x00100000); int KEY_WOW64_64KEY = (0x0100); int REG_OPTION_NON_VOLATILE = (0x00000000); int KEY_ALL_ACCESS = (STANDARD_RIGHTS_ALL | KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY | KEY_CREATE_LINK) & (~SYNCHRONIZE); int ret = 0; try { //将Windows注册表主键名转化成为不带正负号的整形句柄(与平台是32或者64位有关) IntPtr hKey = TransferKeyName(key); //声明将要获取Key值的句柄 IntPtr pHKey = IntPtr.Zero; //获得操作Key值的句柄 int lpdwDisposition = 0; ret = RegCreateKeyEx(hKey, subKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS | KEY_WOW64_64KEY, IntPtr.Zero, out pHKey, out lpdwDisposition); if (ret != 0) { Log2.Log(string.Format("Unable to create key {0} - {1}: {2}!", key, subKey, ret)); return ret; } //关闭注册表转向(禁止特定项的注册表反射) RegDisableReflectionKey(pHKey); //设置访问的Key值 uint REG_SZ = 1; byte[] data = Encoding.Unicode.GetBytes(value); RegSetValueEx(pHKey, name, 0, REG_SZ, data, (uint)data.Length); //打开注册表转向(开启特定项的注册表反射) RegEnableReflectionKey(pHKey); RegCloseKey(pHKey); } catch (Exception ex) { Log2.Log(ex.ToString()); return -1; } return ret; } public static void SetRegistryKey(string key, string subKey, string name, string value) { Log2.Log("SetRegistryKey start."); if (System.IntPtr.Size == 8) { // 写SOFTWARE\Huawei\VirtualDesktopAgent,需要关闭注册表重定向,再写64位路径的注册表 int ret = RegUtil.Set64BitRegistryKey(key, subKey, name, value); if (ret != 0) { Log2.Log(string.Format("Failed to write Reg {0}\\{1}\\{2},return {3}", key, subKey, name, ret)); } } try { Microsoft.Win32.Registry.SetValue(key + "\\" + subKey, name, value); } catch (Exception ex) { Log2.Log(ex.ToString()); } Log2.Log("SetRegistryKey exit."); } public static string GetRegistryValue(string path, string key) { RegistryKey regkey = null; try { regkey = Registry.LocalMachine.OpenSubKey(path); if (regkey == null) { Log2.Log("Cannot find Registry path:" + path); return null; } object val = regkey.GetValue(key); if (val == null) { Log2.Log("Cannot find Registry key:" + key); return null; } return val.ToString(); } catch (Exception ex) { Log2.Log(ex.ToString()); return null; } finally { if (regkey != null) { regkey.Close(); } } } } }
主函数进行操作注册表
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace Regedit { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //public const string vLanID_X86 = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; string Winrarpath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WinRAR archiver"; string key = "DisplayVersion"; private void Form1_Load(object sender, EventArgs e) { //获取注册表值(32位和64位都可以) string value = Common.GetRegistryValue(Winrarpath,key); lb_version.Text = value; } //改注册表值 private void button1_Click(object sender, EventArgs e) { string value = textBox1.Text.ToString(); Common.SetRegistryKey("HKEY_LOCAL_MACHINE", Winrarpath, "DisPlayVersion", value); string newValue = Common.GetRegistryValue(Winrarpath, "DisPlayVersion"); lb_newVersion.Text = newValue; } } }
结果,32\64位都可以改变