我有一套C# (v2)应用程序,我正在为Win7中的注册表虚拟化而苦苦挣扎(在较小的程度上也是如此)。
我在HKLM\Software\Company中有一个共享注册表配置区域,我的应用程序需要访问该区域...在Vista之前,所有内容都只是根据需要写入和读取该位置。
代码适当地检测到写入该注册表项的失败,并将适当地回退(改为写入HKCU,并通知用户它们所应用的设置只会影响当前用户)。
在Vista中,注册表虚拟化打破了这一切,因为我们用于HKLM写入的访问检查将以静默方式“成功”,并虚拟化到HKCR\VirtualStore\Machine...而不是。在这种情况下,用户会认为他们已经保存了计算机范围的配置,但实际上只写入了虚拟存储。
遗憾的是,即使尝试枚举HKLM注册表项上的权限,也会显式返回结果,表明用户是否拥有访问权限。
当我们添加Vista支持时,我们使用的变通方法是对HKLM执行探测写入...然后签入HKCR\VirtualStore\Machine...对于相同的值,请注意,如果找到该值,则会发生虚拟化。
Win7似乎(再次)打破了这一点,因为对显式虚拟位置(HKCR)的查询现在显示来自HKLM位置的合并结果,即使写入未虚拟化。
有没有人有任何建议来解决这个问题?
限制:-我需要一个不需要提升的解决方案(当我没有管理员级别的权限时,我将在HKCU中回退到每个用户的配置,但我需要能够可靠地检测到这种情况)。
发布于 2009-08-24 13:06:58
这是一个很好的问题,+1 (为什么它是社区维基,它值得加分!)
通常,有一组规则(您遇到的规则会随着时间的推移而变化)来控制UAC是否在起作用,从而隐含地控制注册表虚拟化。
Registry Virtualization rulesets documentation in MSDN的一些重要部分包括:
jeffamaphone的
如果您无法影响以上任何内容,这是最理想的,因此您希望检测UAC虚拟化是否适用于当前上下文,请使用this answer to a what might at first not appeat to be a related question。(显然,你仍然需要决定它是否适用于你正在操作的特定键,这是一个移动的目标,如果可以避免的话,你显然不想实现需要跟踪更改的代码-但在大多数情况下,它应该相对清晰。)
发布于 2009-06-16 17:07:27
发布于 2009-06-17 03:54:33
请注意,HKCR
本身就是一个虚拟化存储,是HKLM\Software\Classes
和HKCU\Software\Classes
的组合。
最好的方法是甚至不让注册表虚拟化发生。首先,检查用户在运行时是否被提升,然后您可以通知用户,更改只会在当前用户开始更改之前应用于当前用户。
首先,通过检测您是否是提升的管理员,您可以在HKLM即将虚拟化时避免写入HKLM。
示例:
private bool IsAdministrator
{
get
{
WindowsIdentity wi = WindowsIdentity.GetCurrent();
WindowsPrincipal wp = new WindowsPrincipal(wi);
return wp.IsInRole(WindowsBuiltInRole.Administrator);
}
}
注意:我不是用C#编写代码,示例是从问题How can I detect if my process is running UAC-elevated or not?中提炼出来的
https://stackoverflow.com/questions/1002709
复制相似问题