Hive 注册表那点事( 5.0 VS 6.0 )
现象
5.0 移置到 6.0 上的时候,发现 Hive-Registry 无效,具体的现象是在控制面板中屏幕校准后 Cold Boot 机器校准数据丢失。
环境变量 PRJ_ENABLE_REGFLUSH_THREAD 和 PRJ_ENABLE_FSREGHIVE 配置为 1 ,同时注册表项 "RegistryFlags " 配置为 0 。
分析
首先温习一下 Hive 注册表信息更新的相关基本知识
通过配置注册表 HKEY_LOCAL_MACHINE/init/BootVars 下的注册项 "RegistryFlags " 来配置 Hive 注册表的数据更新方法。
注册项 "RegistryFlags " 可能的值及其含义如下:
Dword value | Description |
none or 0 | Default setting. Flushes the registry nondeterministically . |
1 | Enables aggressive flushing |
2 | Disables background flushing |
详细解释如下:
当配置为 1 的情况下,将使用 Aggressive Flush 的方式来更新 Hive 数据,也就是 Flush On Close ,即在每次调用 RegCloseKey 的时候会更新一次注册表,显然比较浪费系统资源。
当配置为 0 的情况下,使用 Lazy Flush 方式更新注册表,这个也是系统默认的情况。在这种配置情况下,如果依然想保存 Hive 注册表中的更改项的话,有两种如下两种选择:
>> 系统关机前调用 API RegFlushKey 将修改的注册表项写入到存储设备上,如果保存成功将返回成功的标记。
>> 配置环境变量 PRJ_ENABLE_REGFLUSH_THREAD 来创建 Flush 进程来定期更新 Hive 注册表的改动项。
创建的 Flush 线程的优先级
[HKEY_LOCAL_MACHINE/System/ObjectStore/RegFlush ] ; To monitor the flushing from an external process add "ActivityName " registry value. ; The activity name is a global named event that filesystem will signal on Registry Activity. ; "ActivityName "="" ; Create an thread in filesys to perform flushing "SpawnThread "=dword:1 ; Make the thread IDLE priority "FlushPriority256"=dword:FF ; ActivityThreshold specifies the # of reg activity before we force a flush "ActivityThreshold "=dword:100 ; Timeout period in ms for a flush (flush occurs if there have been some changes during this period). "FlushPeriod "=dword:1D4C0 |
系统会按照 SpawnThread 新建一个优先级为 FlushPriority256 的线程,按照 FlushPeriod 周期性地去检查注册表的变化并加以保存。
本案的分析
本文要重点说明的就是这个地方, 5.0 中和 6.0 中 "FlushPeriod " 的默认值是不一样的, 5.0 中默认值为 0x3E8 即 1000ms ,而 6.0 中为 0x1D4C0 ,即 120000ms 。这个地方的差异就造成了在 6.0 系统下注册表的修改值不能够及时的进行保存。
针对 120000ms 的情况,也就是说,当你修改了注册表后,修改的注册表值将会在大约 120000ms 后才刷新到存储设备上,这也造成了在 6.0 上 Hive 注册表不能够保存的问题。
解决方法
为了在 6.0 能够及时的保存注册表信息,需要将默认的 "FlushPeriod " 的值改为比较小的值,可以在 Platform.reg 中添加如下的值来覆盖系统的默认值:
[HKEY_LOCAL_MACHINE/System/ObjectStore/RegFlush ] ; Timeout period in ms for a flush (flush occurs if there have been some changes during this period). "FlushPeriod "=dword:3E8 |
其实 6.0 上支持 Hive-Registry ,还需要比 5.0 上多配置一个环境变量即 PRJ_ENABLE_FSREGHIVE ,这个也应该时 6.0 的一个 Bug 。
附带说一句, Windows Mobile6.5 上也存在类似的问题,在此不再赘述。