基于重启后消失的注册表键值的详细介绍

今天遇到一个bug,折腾了半天才解决掉,分享给大家。
Bug描述
一位开发人员调用下面的代码来创建一个注册表键值:


代码如下:

HKEY hKey;
if(::RegOpenKeyEx(HKEY_CURRENT_USER, DemoRegKey, 0, KEY_WRITE, &hKey) != ERROR_SUCCESS)
{
    RegCreateKeyEx(HKEY_CURRENT_USER, DemoRegKey, 0, NULL, REG_OPTION_VOLATILE
        , KEY_ALL_ACCESS   , NULL   , &hKey, NULL);       
}

执行后,成功的在注册表编辑器中看到了键值,后续从中获取值等代码没有任何问题。
提交测试后发现,当系统重启后,上面的程序创建的注册表键值都没有了,导致后面读取键值的代码都报错。
Why?
随后我调整了代码,发现下面的代码在重启后得到的错误码是2


代码如下:

LONG lRet;
lRet = ::RegOpenKeyEx(HKEY_CURRENT_USER, DemoRegKey, 0, KEY_WRITE, &hKey);

执行这段代码lRet的值是2. 错误码2的意思是:系统找不到指定的文件。 对于注册表函数而已,就是对应的键不存在。
调试后发现,创建注册表的代码的确成功执行了,在注册表中也可以看得到。同时,再调用读取键值的代码,也没有任何问题。但是一旦重启电脑,路径就不存在了,里面保存的键值都没有了。
看来是某些程序删掉了我的键值,于是查找所有删除键值的代码,没有找到。
在重启前将所有的程序都删除掉。但是重启后,该死的键值还是没有出现。
看来是系统或者其它程序删除的。难道我的键值和某些程序的键值重名了?好,这次用guid做键名,还是重启后没有了。
哇哇,真是抓狂啊。
这时候,我回过头来再细看所有创建注册表相关的代码,因为必定是我的程序导致键值消失的。
我注意到了REG_OPTION_VOLATILE  这个奇怪的参数。
MSDN之后,我终于找到了原因,就是这个参数造成的。
原因
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. The RegSaveKey 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);

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

(0)

相关推荐

  • 基于重启后消失的注册表键值的详细介绍

    今天遇到一个bug,折腾了半天才解决掉,分享给大家.Bug描述一位开发人员调用下面的代码来创建一个注册表键值: 复制代码 代码如下: HKEY hKey;if(::RegOpenKeyEx(HKEY_CURRENT_USER, DemoRegKey, 0, KEY_WRITE, &hKey) != ERROR_SUCCESS){    RegCreateKeyEx(HKEY_CURRENT_USER, DemoRegKey, 0, NULL, REG_OPTION_VOLATILE       

  • 利用InstallShield获取注册表键值的脚本

    Use  nvType = REGDB_NUMBER;  szKey = "\\SYSTEM\\CurrentControlSet\\Servic  es\\{58ECC408-265E-4342-9DA4-70BF1796D81D}\\Parameters\\Tcpip";  szName = "EnableDHCP"  RegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE );  RegDBGetKeyvalueEx ( szKey,

  • MybatisPlus中插入数据后获取该对象主键值的实现

    实体对象 主键IdType要设置为AUTO 表示数据库ID自增 @Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) public class Employee implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO) priv

  • Java探索之Hibernate主键生成策略详细介绍

    1.increment 由Hibernate从数据库中去除主键的最大值(每个session只取一次),以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的数据库,因此可以跨数据库. <id name="id" column="id"> <generator class="increment" /> </id> Hibernate调用org.hibernate.id.IncrementGenerator类

  • 用批处理删除注册表健值的方法分享

    一个基本的格式参考 reg delete KeyName [/v ValueName | /ve | /va] [/f] KeyName [\\Machine\]FullKey Machine 远程机器名 - 忽略当前机器的默认值. 远程机器上只有 HKLM 和 HKU. FullKey ROOTKEY\SubKey ROOTKEY [ HKLM | HKCU | HKCR | HKU | HKCC ] SubKey 所选 ROOTKEY 下的注册表项的全名. ValueName 所选项下的要删

  • python读取注册表中值的方法

    在Python的标准库中,_winreg.pyd可以操作Windows的注册表,另外第三方的win32库封装了大量的Windows API,使用起来也很方便.不过这里介绍的是使用_winreg操作注册表,毕竟是Python自带的标准库,无需安装第三方库. 下面的例子是通过Python获取Windows XP下已经安装的补丁号.Windows的补丁号都在"HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft\\Updates"下,通过循环下面所有的目录节点,如果找

  • 强大的 Angular 表单验证功能详细介绍

    Angular 支持非常强大的内置表单验证,maxlength.minlength.required 以及 pattern.使用 Angular 的内置表单校验能够完成绝大多数的业务场景的校验需求,但有时我们还需要实现更为复杂的表单校验功能,这时可以使用 Angular 提供的表单自定义校验(Custom Validator).下面,我们就来了解一下如何使用 Angular 的自定义表单校验 效果图: 1.首先,来创建我们的注册组件(register),并在模版中显示一个简单的表单 <h3 cl

  • 注册表编辑器的注册表修改

    ●注册表编辑器的自动刷新设置: 打开HKEY_CURRENT_USER\Software\Microsoft\RegEdt32\Settings子键分支,在右边的窗口中新建一个字符串值"AutoRefresh",将其值设为1. ●注册表修改的只读功能: Windows NT/2000的三十二位注册表编辑器中提供了注册表修改时的只读设置,这主要是为了防止注册表的修改错误.Windows XP将十六位和三十二位的注册表编辑器合并为一个,但未直接提供注册表修改的只读功能,我们需要对之进行修改

  • 给注册表编辑器装地址栏

    无论是Windows 98还是Windows XP,系统默认的注册表编辑器都不能摆脱这样的事实:只要是修改注册表键值,就必须要在注册表编辑器中将键值逐级展开.大家也许想过,如果注册表编辑器拥有像IE浏览器那样的地址栏,只需将键值具体的路径键入或复制到地址栏中就能实现快速定位的话,不就可以很快找到键值了吗? RegEditX (Registry Editor Extensions)就是给系统默认的注册表编辑器添加地址栏的一款工具软件.该软件很小,但却能给注册表编辑器增加很实用的功能,而且它是免费提

  • 完整的注册表操作实例 VBS脚本

    ①创建主键.创建各类型的键值. ②读取键值并分析键值类型. ③枚举主键及键值. ④判断键或键值是否存在. ⑤查询注册表键的操作权限. ⑥监视注册表根键.主键.键值,当发现变动时提示. 复制代码 代码如下: '''注册表查询/操作 On Error Resume Next Const HKEY_CLASSES_ROOT = &H80000000'''设置注册表5大根键,HKCR-----------① Const HKEY_CURRENT_USER = &H80000001'''HKCU C

随机推荐