Windows何时将注册表更改写入磁盘?


43

TL; DR:

我注意到,如果我更改了注册表,然后硬关闭了Windows 10系统,则重新启动后不会出现注册表更改。

我还注意到,删除休眠文件可能会影响Linux恢复工具以脱机状态对Windows注册表进行更改的能力。删除休眠文件后,该工具似乎无法进行永久更改。我将在下面列出具体示例。

范例1:

  • 我在“ HKLM \ SOFTWARE”中添加了一个名为“ 1111”的密钥。然后,我按住电源按钮5秒钟,以自动关闭电源。
  • 测试键
  • 当我备份注册表时,该键及其值不见了:
  • 测试键消失了
  • (这些图像是出于格式化目的而编辑的)

范例2

  • 在注册表中进行更改(使用regedit)
  • 休眠系统
  • 引导至Linux恢复工具
  • 删除休眠文件为了挂接磁盘。
  • 阅读Windows注册表(通过恢复工具)
  • 注册表更改不见了。

这似乎相当于硬关闭机器。

范例3:

我在以下情况下看到陌生人的行为:

  • 休眠盒
  • 引导至Linux恢复工具并删除休眠文件
  • 更改注册表(通过恢复工具)
  • 重新启动盒子

这些更改也不会反映在注册表中。

那么这是怎么回事?

  • Windows 10何时将注册表更改写入磁盘?
  • 为什么删除休眠文件(在示例3中)会阻止从恢复工具进行的注册表更改反映在下次启动时?

希望得到一些澄清!


2
“重新启动后,不会出现注册表更改。” -注册表更改直到重新启动后才生效,通常,仅文件浏览器必须重新启动。如果实际需要重新启动,则这完全取决于注册表更改的意图。修改后的实际密钥会得到解答。
Ramhound18年

8
硬关机是什么意思?按住电源按钮直到它关闭?该过程绕过写出任何未决的磁盘高速缓存写操作。
DavidPostill

2
@Ramhound我知道它没有生效,但是为什么还没有将它写入磁盘呢?我进行编辑,先关闭电源,然后再进行更改。那时它是否在内存中生效并不重要
Shrout1

2
@ Shrout1-为什么要强制关闭机器而不是安全关闭机器?
Ramhound

6
@Ramhound我正在运行测试,以查看如果系统无法正常关闭会发生什么。我知道是随机的,但是我需要确切地知道这是如何提交给内存的,这样,如果处理不当,我们就不会在系统上丢失任何内容。
Shrout18年

Answers:


54

TL; DR:正确关闭系统。


休眠与关闭无关,它与挂起至RAM(休眠)密切相关,只是将RAM的内容推送到磁盘以使其读回并从系统停止运行的确切位置恢复操作。

如果您希望更改继续存在,则需要禁用休眠 Windows Fastboot(这是休眠的子集)。或者,您实际上可以重新启动而不是休眠然后重新启动。

更改未保留的原因是,除了休眠文件之外,尚未将其写入磁盘。您要删除的文件,这意味着文件系统可能必须修复自身并返回到“最后一次正常”状态。

当系统处于休眠状态时,将有几个关键的文件系统结构可能尚未写到磁盘上,而是在RAM中。从休眠状态恢复后,系统将期望磁盘处于非常特殊的状态,并且磁盘缓存和重要的系统文件可能会保存到休眠文件中,而不是保存到实际磁盘中。

如果执行适当的关闭操作,则Windows将正确地将工作内存刷新到磁盘,然后在断电之前将磁盘干净地卸载。

要强制正常关闭,请打开命令提示符并键入

shutdown /s /f /t 0

/s是“关机”,/f强制使用和/t 0表示“现在”(时间= 0秒)

或者,您可以仅禁用快速启动和休眠。

HowtoGeek上了解更多信息:关闭并不能完全关闭Windows 10(但是重新启动可以)


与您执行硬关闭有关的问题是,不能保证Windows在进行更改的同一毫秒(甚至分钟)内将任何更改写出到磁盘上。几乎可以肯定会在几分钟之完成编写,但是实际编写的可能性会随着时间的流逝而增加。它不太可能立即被写入,然后您进行更改的时间附近,概率急剧增加,并且几乎可以肯定会在一小时内被写入。

事实是,通过强制硬关闭,您没有给系统机会安全地将更改写入磁盘。

大多数现代文件系统都是为了以最安全的方式进行更改而编写的。在过去,它们被称为“原子的”,因为变化要么已经发生,要么没有发生。

今天,我们将它们称为Journalled文件系统,因为它们保留了将要发生的操作的日志,如果系统发生故障并重新引导,这些日志可以还原或前滚。从电源故障启动后,系统将检查日志,并针对每个事务检查实际文件数据是否已写入磁盘并且是否“良好”。如果是,则转换前滚并完成,否则,它回滚到旧数据。

通过使用此顺序,磁盘几乎始终处于易于修复的状态。

但是通过强制系统意外关闭电源,您不能保证事务处理是否进展到足以进行修复的前滚,并且很有可能像Linux这样的操作系统对Windows的事务历史记录的关心程度不如Windows。而不是仅仅进行使所有内容都向后而不是向前滚动的更改。

如果您重新启动进入Windows,它可能会尝试或能够正确修复磁盘,因为它对文件系统有更深入的了解。


谢谢!感谢您的答复:)我关闭了休眠模式,重新启动并重新运行了相同的测试。示例1的结果相同,不涉及任何休眠文件。看来注册表更改仅在注销/关闭过程中的某个时间点写入。。我也同意,从中断的休眠状态唤醒时,系统可能正在寻找“最后一个好”状态-它倾向于运行完整性检查。
Shrout18年

1
嗯...所以我下载了sysinternals“ sync”,它将写缓存强制到磁盘上,却什么也没做(仍然在硬关闭时丢失了键/值)。我还运行了进程浏览器,并查看了Regedit属性中的“磁盘I / O”。它已读取I / O,但未写入I / O。这使我认为它可能正在等待关机...您是否知道任何过于干燥的M $文档可能会清楚地说明这一点?再次感谢你的帮助!!
Shrout18年

11
NTFS日记不保证有关文件数据。仅仅是为了使NTFS元数据保持一致,因此不会导致文件系统损坏。单个文件仍然可以记录部分更改,从而破坏了文件。有事务性NTFS,但是不推荐使用,很少使用。这也是为什么数据库引擎保留自己的日志以保持数据一致性的原因。另请参阅blogs.msdn.microsoft.com/oldnewthing/20130101-00/?p=5673
Bob的

2
@ Shrout1假设注册表更改在回写缓存中处于挂起状态。完全有可能将它们分别管理,而这与文件系统,缓存或其他方式无关。例如,“最后一次正确的配置”仅在成功启动后才更新。(我对注册表的内部了解不足,无法确定何时保存更改。然后可能涉及到TxR。)
Bob Bob

1
您是否有理由要强制关机?AFAIK仅强制关闭正在运行的应用程序,除了杀死您无法关闭的应用程序外,无济于事,并且如果您不知道自己在做什么,那么更有可能丢失某些未保存的更改这样做或将某些应用程序置于不可恢复的状态-我真的不会称其为“适当的”关闭。
NotThatGuy

39

MSDN页面上记录的RegFlushKey

调用RegFlushKey是一项昂贵的操作,因为它消耗磁盘带宽并阻止正在刷新的注册表配置单元中所有进程修改所有键的修改,直到刷新操作完成为止,这会严重影响系统范围的性能。仅当应用程序必须确保注册表更改在修改后立即保留在磁盘上时,才应显式调用RegFlushKey。对键所做的所有修改对于其他进程都是可见的,而无需将其刷新到磁盘。

另外,注册表具有“惰性刷新”机制,该机制可以定期将注册表修改刷新到磁盘上。除了此常规的刷新操作外,注册表更改还会在系统关闭时刷新到磁盘。允许“惰性刷新”刷新注册表更改是管理注册表写入磁盘上注册表存储的最有效方法。

这表明,除了立即将特定的密钥刷新到磁盘(这将其他所有人锁定到注册表之外,直到刷新完成)之外,还会自动定期刷新注册表:没有给出时间,但大概至少比刷新时间长。在编写密钥和硬关机之间等待的时间。另外,正如您已经知道的那样,它在关闭时会刷新。

您可以RegFlushKey在操纵所述密钥的软件中使用该功能,也可以创建一个附加工具来强制将注册表项立即写入磁盘(如果这对您的使用情况至关重要)。


嘿! 如果您链接到以下MSDN文章,我将为您提供此链接:在Windows 8或Windows Server 2012上保存应用程序注册表更改并添加简短的blockquote。您的回答将我引向了那篇文章的兔子洞,它基本上说出了您所做的同样的事情。非常感谢!
Shrout18年

但是有人知道用户如何调用RegFlushKey吗?
斯科特(Scott)

@Scott似乎必须用代码完成...文章中列出的MSDN文章有一个C ++示例,我已经在其他地方用C#实现了它。不确定是否可以从命令行完成。
Shrout18年

3
@Scott:如果我会感到震惊sync 冲洗注册表到磁盘。只是没有任何意义。为什么刷新文件系统缓存(配置管理器使用不是相反)会突然刷新配置管理器自己的缓存?如果甚至根本不存在,它甚至不知道高级缓存的结构是什么。
Mehrdad

1
@Scott有办法。该API已被链接。有一些工具可以为您提供GUI来调用任意Win32函数。事情是...这是一个实现细节。如果您公开它,人们就会依赖它,那么您将无法对其进行更改。同样值得注意的是,系统磁盘与可移动介质完全不同。系统磁盘用于许多需要始终打开手柄的事物(例如页面文件)。Windows不支持卸载系统分区,因此不需要此“功能”。另外...请尽量保持评论中立。您讨厌Windows,我们明白了。
基本

14

TL; DR:在正确的时间执行此操作非常小心。

上面的文档FSCTL_MARK_AS_SYSTEM_HIVE说:

FSCTL_MARK_AS_SYSTEM_HIVE控制代码通知文件系统中指定的文件包含注册表的系统配置单元。文件系统必须在适当的时候将系统配置单元数据刷新到磁盘上,以避免死锁并确保数据完整性。

我认为没有比这更公开的细节了。

请记住,刷新文件系统并不意味着刷新注册表,因为注册表可以在文件系统之上执行缓存。首先要刷新注册表,您需要以某种方式导致NtFlushKeyZwFlushKey调用您感兴趣的密钥。


哦,好抓住!那就是我新喜欢的MSDN主义:恰在适当的时机。我以前最喜欢的是“在包含UNION,UNION ALL,EXCEPT或INTERSECT运算符的查询中指定TOP子句时请谨慎使用。可以编写返回意外结果的查询”,这对“此功能是严重损坏,无法满足任何合理的人的期望,我们将对其进行记录,而不是对其进行修复”。
davidbak

@davidbak:大声笑,在MSDN的辩护中,我真的看不到他们可以提供用户应该依靠的更多细节。
Mehrdad

哦,你是对的。显然,这只是文件记载,是对长期以来的欧盟和解的影响,在该和解中,微软必须记录所有API,无论它们内部如何。您链接的页面甚至说:“只有内核级组件才能使用此文件系统控制代码”,这是一个强大的提示,可让您放手。不过,“ 恰到好处的时刻 ” —有一天,我将用“仅在恰好的时刻仅调用此方法”记录我的一些API,然后看看会发生什么
。...– davidbak

@davidbak:我觉得你有点...激动。:-P我的猜测是对此文档进行了记录,目的是让文件系统驱动程序知道哪个文件包含SYSTEM注册表配置单元,这可能很重要,因为它们不会尝试在该文件同时向注册表中写入任何内容正在刷新到磁盘。我对此没有任何证据。这只是我认为可以想到的原因之一。我对此有一个疑问,那就是为什么磁盘驱动器也不需要知道这一点。
Mehrdad
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.