以编程方式锁定注册表键,以避免并发问题。

3

我正在编写一个应用程序,需要按特定顺序在一个键中写入注册表值。同时,其他应用程序也可能在同一时间写入该键。

有没有一种方法可以暂时锁定注册表键进行写入操作,以避免多个进程同时写入该注册表键,导致数值混乱/顺序错误?

例如,我需要写入HKCU\Software\Company\Product\下面已经包含以下数值:

  • Start1 = "abc"
  • Start2 = "def"
  • Start3 = "ghi"

因为最后一个是Start3,所以我需要创建Start4

问题是,如果另一个进程同时运行,并检测到Start3是最后一个,则会覆盖我刚创建的Start4(因为由于并发性,它看不到它)。

有什么好的方法可以防止这种情况发生?

我无法控制哪些(或多少)应用程序正在写入此键,因此无法要求它们暂停等任何操作...

我正在寻找类似下面的伪代码:

Registry.Lock("HKCU\Software\Company\Product\");
Registry.Write("Start4", "jkl");
Registry.Unlock("HKCU\Software\Company\Product\");

1
你可能想要查看 RegOpenKeyTransacted - Jim Rhodes
1
这些键非常具体,不是随意的程序就能够轻而易举地更改值的类型。所以也许有一个潜在的协调不足,就像这篇旧的博客文章中所描述的那样?https://devblogs.microsoft.com/oldnewthing/20110310-00/?p=11253 | 或者你实际上想要的是写作程序中的单实例模式?https://www.meziantou.net/single-instance-of-an-application-in-csharp.htm - Christopher
1
"事务被回滚"意味着您将收到一个错误代码,此时您可以检查新的状态并重试(例如,您会发现Start4已经存在)。 - rustyx
事务注册表 API 相对于全局互斥锁有什么优势?你的应用程序必须同意使用事务 API,但它们也可以同意使用互斥锁,这样做肯定会简化事情。 - zett42
@zett42 正如我在问题中所说:我无法控制其他写入相同键的应用程序...换句话说:它们不是我的应用程序...我正在编写的密钥是市场上许多第三方应用程序使用的密钥。 - Lindsey1986
显示剩余3条评论
2个回答

5

很不幸,看起来我将要回答自己的问题。

写入和删除注册表数据

在写操作期间无法锁定注册表键以同步访问数据。但是,您可以使用安全属性控制对注册表键的访问。有关更多信息,请参阅注册表键安全性和访问权限

可以在单个事务内执行多个注册表操作。要将注册表键与事务相关联,应用程序可以使用RegCreateKeyTransactedRegOpenKeyTransacted函数。有关事务的更多信息,请参见内核事务管理器

来源:https://learn.microsoft.com/en-us/windows/win32/sysinfo/writing-and-deleting-registry-data


回答自己的问题从来不是件坏事。你能够帮助自己,并通过发布答案来帮助将来的其他人。 - DetectivePikachu
不要忘记标记自己的内容,这样寻求帮助的人就可以轻松找到他们最有可能想要的东西。 - Drake Wu
感谢 @DrakeWu-MSFT 的提醒。在我发布答案时,我没有足够的声望来标记自己的答案为有效答案...但现在我有了。 - Lindsey1986

1

您需要使用适当的同步方式,使用互斥函数。注册表 API,像大多数 Windows API 一样,不是线程安全的。


谢谢@Michael。不幸的是,我无法控制写入此键的应用程序(或数量),因此我无法通过互斥或任何其他方式与它们合作,因为我们彼此不知道... - Lindsey1986
1
@Lindsey1986,“无法控制写入此键的应用程序数量或类型”——这正是全局命名互斥量可以解决的问题!您的应用程序只需要就互斥量名称达成一致,而不必了解彼此的其他信息。 - zett42
3
他无法控制的应用程序如何在互斥名称上达成一致? - DetectivePikachu
@ĴošħWilliard,OP似乎已经有足够的控制权让他们同意使用事务注册表API。如果是这样,他们也可能会同意使用互斥锁。 - zett42
@zett42 我无法控制写入相同键的其他应用程序...它们是我不知道、无法控制的第三方应用程序,它们也不知道我的应用程序的存在。这些应用程序之间不可能有任何形式的合作... - Lindsey1986

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接