惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
博客园 - 叶小钗
The Cloudflare Blog
T
Tailwind CSS Blog
Hugging Face - Blog
Hugging Face - Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
月光博客
月光博客
小众软件
小众软件
罗磊的独立博客
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 聂微东
量子位
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
宝玉的分享
宝玉的分享

博客园 - 林杰的博客

7z系列之一:7zip SDK中C++模块的编译 WORD2012 中使用“全屏阅读” Office2012中使用“冻结窗格”功能锁定标题栏 开发工具:Visual Studio 2005下方便宜用的代码行统计工具 为Visual Assist设置快捷键 Visual Studio 2010的Python支持工具 Linux 使用pid文件结束nginx 让Win7资源管理器显示图片内容预览 Python 单元测试带案例名称输出 Linux 系统安装配置NTP时间服务器 Editplus中.proto文件的高亮文件 c#美味: 微软图表控件MSChart安装部署 测试工具:用性能监视器查看程序的性能 C#美味:Linq入门 讲座 C++零食:使用Unicode版的预定义宏__FUNCTION__ C++零食:VC中使用ForceInclude来强制包含stdafx.h C++零食:WTL中使用双缓冲避免闪烁 C++零食:wprintf 中使用%I64d格式化输出LONGLONG C++零食:HRESULT 与 Windows Error Codes 不是一回事
C++零食:重启后消失的注册表键值
林杰的博客 · 2010-09-20 · via 博客园 - 林杰的博客

今天遇到一个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);        

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

参考资料

RegCreateKeyEx Function

http://msdn.microsoft.com/en-us/library/ms724844(VS.85).aspx