C#操作注册表增删改查及关机能保存问题

2023-05-16


为何用程序写入注册表后,重启机器注册表项就彻底丢失呢
仔细看看RegCreateKeyEx的用法
其中的dwOptions使用:REG_OPTION_NON_VOLATILE
而不是:REG_OPTION_VOLATILE  

重启电脑创建的注册表键值丢失原因

REG_OPTION_VOLATILE  这个参数的意思是创建的注册表键值都位于内存中,不会保存到相应的注册表文件中

英文如下:

All registry keys are created as volatile, and the information is stored in memory and is not preserved when the corresponding registry hive is unloaded. For HKEY_LOCAL_MACHINE, this occurs when the OS is shut down. TheRegSaveKey function does not save volatile registry keys. This flag is ignored for keys that already exist.

所以,重启后这些键值当然就没有了。

解决办法

很简单,使用REG_OPTION_NON_VOLATILE 即可


RegCreateKeyEx(HKEY_CURRENT_USER, DemoRegKey, 0, NULL, REG_OPTION_NON_VOLATILE
            , KEY_ALL_ACCESS   , NULL   , &hKey, NULL);        
  

REG_OPTION_VOLATILE可以用在测试上。一重启,之前创建的键值都没了。

而若想重启之后注册表键值也仍然保留的话就用REG_OPTION_NON_VOLATILE

 REG_OPTION_NON_VOLATILE:

该宏是RegCreateKeyEx函数的参数可选项。

LONG RegCreateKeyEx( HKEY hKey,

LPCWSTR lpSubKey,

 DWORD Reserved,

LPWSTR lpClass,

DWORD dwOptions,

REGSAM samDesired,

 LPSECURITY_ATTRIBUTES lpSecurityAttributes,

 PHKEY phkResult,

LPDWORD lpdwDisposition );

看看MSDN对它的说明:

Default setting. All registry keys are created as non-volatile and the information stored in memory is preserved when the OS is restarted. The RegSaveKey function saves keys that are non-volatile.

翻译:默认设置。 所有注册表项 创建 作为非易失性 和 操作系统 重新启动 时保留 在内存 中存储的信息 。 RegSaveKey 功能 键 是 非易失性 保存 。

意思是说如果参数 dwOptions 选择REG_OPTION_NON_VOLATILE,则通过RegCreateKeyEx创建的注册表是永久的,不会因为计算机的重启而消失。相反参数选择REG_OPTION_VOLATILE,则表明创建的注册表是临时的,计算机重启后该注册表不存在。

dwOptions

[in] Registry key options. The following table shows the possible values for this parameter.

ValueDescription
REG_OPTION_NON_VOLATILEDefault setting. All registry keys are created as non-volatile and the information stored in memory is preserved when the OS is restarted. The RegSaveKey function saves keys that are non-volatile.
REG_OPTION_VOLATILEAll registry keys are created as volatile, and the information is stored in memory and is not preserved when the corresponding registry hive is unloaded. For HKEY_LOCAL_MACHINE, this occurs when the OS is shut down. The RegSaveKey function does not save volatile registry keys. This flag is ignored for keys that already exist.

一.注册表巢

     在注册表中,最上面的节点是注册表巢(registry hive)。

     HKEY_CLASSES_ROOT(HKCR)    包含系统文件类型的细节,以及应用程序可以打开的文件类型,它还包含所有COM组件的注册信息。

     HKEY_CURRENT_USER(HKCU)    包含用户目前登陆的机器的用户配置,包括桌面设置、环境变量、网络和打印机连接和其他定义用户操作环境的变量。

     HKEY_LOCAL_MACHINE(HKLM)    是一个很大的巢,其中包含所有安装到机器上的软件和硬件的信息。

     HKEY_USERS(HKUSR)                包含所有用户的用户配置。

     HKEY_CURRENT_CONFIG(HKCF)  包含机器上硬件的信息。

二.注册表类及常用属性和函数


using Microsoft.Win32;  

这个命名空间包含了注册表相关的类。Registry类、RegistryKey类。  

Registry类封装了注册表的七个基本主键:  

Registry.ClassesRoot  

对应于HKEY_CLASSES_ROOT主键   

Registry.CurrentUser  

对应于HKEY_CURRENT_USER主键  

Registry.LocalMachine  

对应于 HKEY_LOCAL_MACHINE主键  

Registry.User  

对应于 HKEY_USER主键  

Registry.CurrentConfig  

对应于HEKY_CURRENT_CONFIG主键  

Registry.DynDa   

对应于HKEY_DYN_DATA主键  

Registry.PerformanceData  

对应于HKEY_PERFORMANCE_DATA主键  

RegistryKey类封装了对注册表的基本操作。包括读、写、删等操作的常用函数:   
Name键的名称(只读)
SubKeyCount键的子键个数
ValueCount键包含的值的个数
Close()关闭键
CreateSubKey()创建给定名称的子键
DeleteSubKey()删除指定的子键
DeleteSubKeyTree()递归删除子键及其所有的子键
DeleteValue()从键中删除一个指定的值
GetAccessControl()返回指定注册表键的访问控制表
GetSubKeyNames()返回包含子键名称的字符串数组
GetValue()返回指定的值
GetValueKind()返回指定的值,检索其注册表数据类型
GetValueNames()返回一个包含所有键值名称的字符串数组
OpenSubKey()返回表示给定子键的RegistryKey实例引用
SetAccessControl()把访问控制表(ACL)应用于指定的注册表键
SetValue()设置指定的值

 

三 注册表项的创建、打开、删除
   1,创建
  

 //使用CreateSubKey()在SOFTWARE下创建子项test
RegistryKey hklm = Registry.LocalMachine;
//如果想关机也能保存不释放需使用CreateSubKey的带有设置dwOptions的同名方法并设置为
//REG_OPTION_NON_VOLATILE
RegistryKey hkSoftWare = hklm.CreateSubKey(@"SOFTWARE\test");
hklm.Close();
hkSoftWare.Close();
  

       2,打开


//使用OpenSubKey()打开项,获得RegistryKey对象,当路径不存在时,为Null。第二个参数为true,表示可写,可读,可删;省略时只能读。
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftWare = hklm.OpenSubKey(@"SOFTWARE\test",true);
hklm.Close();
hkSoftWare.Close();
  

      3,删除


//主要用到了DeleteSubKey(),删除test项
RegistryKey hklm = Registry.LocalMachine;
hklm.DeleteSubKey(@"SOFTWARE\test", true);  //为true时,删除的注册表不存在时抛出异常;当为false时不抛出异常。
hklm.Close();  

四、注册表键值的创建、打开和删除

      1,创建


//主要用到了SetValue(),表示在test下创建名称为Name,值为RegistryTest的键值。第三个参数表示键值类型,省略时,默认为字符串
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftWare = hklm.OpenSubKey(@"SOFTWARE\test",true);
hkSoftWare.SetValue("Name", "RegistryTest", RegistryValueKind.String);
hklm.Close();
hkSoftWare.Close();
  

     2,打开


//主要用到了GetValue(),获得名称为"Name"的键值
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftWare = hklm.OpenSubKey(@"SOFTWARE\test", true);
string sValue = hkSoftWare.GetValue("Name").ToString();
hklm.Close();
hkSoftWare.Close();
  

     3,删除


//主要用到了DeleteValue(),表示删除名称为"Name"的键值,第二个参数表示是否抛出异常
RegistryKey hklm = Registry.LocalMachine;
RegistryKey hkSoftWare = hklm.OpenSubKey(@"SOFTWARE\test", true);
hkSoftWare.DeleteValue("Name", true);
hklm.Close();
hkSoftWare.Close();
  

五、判断注册表项、注册表键值是否存在

复制代码


        //判断注册表项是否存在
        private bool IsRegistryKeyExist(string sKeyName)
        {
            string[] sKeyNameColl;
            RegistryKey hklm = Registry.LocalMachine;
            RegistryKey hkSoftWare = hklm.OpenSubKey(@"SOFTWARE");
            sKeyNameColl = hkSoftWare.GetSubKeyNames(); //获取SOFTWARE下所有的子项
            foreach (string sName in sKeyNameColl)
            {
                if (sName == sKeyName)
                {
                    hklm.Close();
                    hkSoftWare.Close();
                    return true;
                }
            }
            hklm.Close();
            hkSoftWare.Close();
            return false;
        }


        //判断键值是否存在
        private bool IsRegistryValueNameExist(string sValueName)
        {
            string[] sValueNameColl;
            RegistryKey hklm = Registry.LocalMachine;
            RegistryKey hkTest = hklm.OpenSubKey(@"SOFTWARE\test");
            sValueNameColl = hkTest.GetValueNames(); //获取test下所有键值的名称
            foreach (string sName in sValueNameColl)
            {
                if (sName == sValueName)
                {
                    hklm.Close();
                    hkTest.Close();
                    return true;
                }
            }
            hklm.Close();
            hkTest.Close();
            return false;
        }  

复制代码

六、程序自启动程序

复制代码


                //开启程序自启动
                string path = Application.ExecutablePath;
                RegistryKey rk = Registry.LocalMachine;
                RegistryKey rk2 = rk.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run");
                rk2.SetValue("JcShutdown", path);
                rk2.Close();
                rk.Close();



                //关闭程序自启动
                string path = Application.ExecutablePath;
                RegistryKey rk = Registry.LocalMachine;
                RegistryKey rk2 = rk.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run");
                rk2.DeleteValue("JcShutdown", false);
                rk2.Close();
                rk.Close();  

复制代码

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#操作注册表增删改查及关机能保存问题 的相关文章

  • C# WebApi 返回JSON类型

    在默认情况下 当我们新建一个webapi项目 会自动返回XML格式的数据 如果我们想返回JSON的数据 可以设置下面的三种方法 nbsp 1 不用改配置文件 在Controller的方法中 直接返回HttpResponseMessage p
  • c#通过HttpClient来调用Web Api接口

    lt summary gt HttpClient实现Post请求 异步 lt summary gt static async void dooPost string url http localhost 52824 api register
  • c#使用HttpClient调用WebApi

    调用WebApi 可以利用HttpClient来进行Web Api的调用 由于WebA Api的调用本质上就是一次普通的发送请求与接收响应的过程 xff0c 所有HttpClient其实可以作为一般意义上发送HTTP请求的工具 using
  • C#中通过HttpClient发送Post请求

    C 中HttpClient进行各种类型的传输 我们可以看到 尽管PostAsync有四个重载函数 但是接受的都是HttpContent 而查看源码可以看到 HttpContent是一个抽象类 那我们就不可能直接创建HttpContent的实
  • c#中WepAPI(post/get)控制器方法创建和httpclient调用webAPI实例

    一 xff1a WebAPI创建 using System using System Collections Generic using System Linq using System Net Http using System Text
  • c#中Task线程的用法

    1 Task的优势 ThreadPool相比Thread来说具备了很多优势 xff0c 但是ThreadPool却又存在一些使用上的不方便 比如 xff1a ThreadPool不支持线程的取消 完成 失败通知等交互性操作 xff1b Th
  • C# 中对象与JSON字符串相互转换的三种方法

    JSON JavaScript Object Notation JS 对象标记 是一种轻量级的数据交换格式 关于内存对象和JSON字符串的相互转换 xff0c 在实际项目中应比较广泛 xff0c 经过一番搜索 xff0c 找到如下三种方法来
  • 解决VM虚拟机中ubuntu系统上不了网的问题

    最简单的方式 关闭虚拟机在对应的虚拟机上右键 xff0c 点击设置 xff0c 找到网络适配器 xff0c 点击移除 xff0c 再次点击添加 xff0c 将网络适配器再次添加回来 xff0c 点击确定重启虚拟机 如果第一种方式解决不了问题
  • C#中创建圆形/按钮(使用重绘)

    创建圆形按钮挺简单的 public class EllipseButton Button protected override void OnPaint PaintEventArgs pevent GraphicsPath gPath 61
  • c#中控件重绘(放大缩小移动隐藏恢复后不消失)实例

    很重要 一定要重写并在在OnPaint 中用传入的pevent Graphics重绘 并且屏蔽掉父类的OnPaint方法 这样重绘后的图形不论控件怎么操作都不会消失了 using System using System Collection
  • WM_Paint 消息疑问解析

    1 系统何时发送WM PAINT消息 xff1f 系统会在多个不同的时机发送 WM PAINT 消息 xff1a 当第一次创建一个窗口时 xff0c 当改变窗口的大小时 xff0c 当把窗口从另一个 窗口背后移出时 xff0c 当最大化或最
  • Windows 消息ID及定义大全

    表A 1 Windows消息分布 消息范围 说 明 0 xff5e WM USER 1 系统消息 WM USER xff5e 0x7FFF 自定义窗口类整数消息 WM APP xff5e 0xBFFF 应用程序自定义消息 0xC000 xf
  • C++中消息机制阻塞实验

    VC6标准WIN32程序 xff0c Windows消息处理机制 xff1a 1 在注册窗口类时 xff0c 指定了消息处理函数WndProc 2 WinMain xff08 xff09 里有消息循环 xff1a while GetMess
  • C#中控件如何设置透明色

    设置窗体的TransparencyKey 属性 xff0c 为你想要变成透明的颜色 xff0c 比如 xff1a 你把窗体背景色设置成红色 xff0c 然后把TransparencyKey 设置成红色 xff0c 代码 xff1a this
  • SendMessage消息发送原理与死锁处理

    windows是一个消息驱动的系统 xff0c 也是个多任务调度系统 xff0c windows中的线程分为两类 xff0c GUI线程与Worker线程 xff0c 每个GUI线程会关联消息队列 xff0c 当消息处理顺序不当时 xff0
  • C#中PostMessage和SendMessage的参数传递实例

    用 PostMessage SendNotifyMessage SendMessageCallback 等异步函数发送系统消息时 xff0c 参数里不可以使用指针 xff0c 因为发送者并不等待消息的处理就返回 xff0c 接受者还没处理指
  • WindowsAPI中PostMessage与SendMessage的区别

    xff11 返回值意义的区别 xff0c 先看一下 MSDN 里的声明 xff1a LRESULT SendMessage HWND hWnd UINT Msg WPARAM wParam LPARAM lParam BOOL PostMe
  • vnc viewer中文版,超好用的几款vnc viewer中文版

    现在 市面上有着各种各样的vnc viewer中文版软件 xff0c 在日常工作中 xff0c 也不可避免的会使用到vnc viewer中文版软件 毕竟对于我们国人来说 中文版软件更便于使用 你会选择哪一款vnc viewer中文版软件呢
  • c#基于socket的UDP服务器和客户端实例

    基于Udp协议是无连接模式通讯 xff0c 占用资源少 xff0c 响应速度快 xff0c 延时低 至于可靠性 xff0c 可通过应用层的控制来满足 不可靠连接 使用Udp协议通讯需要具备以下几个条件 xff1a 1 建立一个套接字 Soc

随机推荐