• 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_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstallWinRAR archiver ".且Key值为:"DisplayVersion"

      Winrar的版本号在32位机器里的注册表里的路径Path:"HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftWindowsCurrentVersionUninstallWinRAR 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)
                {
                    // 写SOFTWAREHuaweiVirtualDesktopAgent,需要关闭注册表重定向,再写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 = @"SOFTWAREMicrosoftWindowsCurrentVersionRun";
    
    
            string Winrarpath = @"SOFTWAREMicrosoftWindowsCurrentVersionUninstallWinRAR 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;
            }
        }
    }

    结果,3264位都可以改变

  • 相关阅读:
    QML中的states用法
    mako的namespace(四)
    Dynamics CRM2013 按钮自定义开发工具 Ribbon Workbench 介绍
    CRM 导入导出附件上传大小限制控制
    插件(plugin)调试技巧及注意事项
    Dynamics CRM2013 自定义开发工具 Dynamics XRM Tools 介绍
    传递正能量,拒绝负能量!加油
    让人无语的编程环境
    转NET(C#):线程本地存储(ThreadLocal Storage)之ThreadStatic, LocalDataStoreSlot和ThreadLocal<T>
    转javaThreadLocal
  • 原文地址:https://www.cnblogs.com/javier520/p/10653372.html
Copyright © 2020-2023  润新知