2014-02-12 36 views
1

(从大卫赫弗南试图建议后更新)当心的Windows 8.1注册表中读取虚拟化并不适用于64位应用程序

我有一个传统的Win32本机应用程序(德尔福6)该HKEY_LOCAL_MACHINE下写入值注册表\ Software \\键。这些值稍后将被几个其他传统Win32本机应用程序和一个新的.NET应用程序读取。 .NET应用程序构建AnyCPU,因此以64位图像的形式执行。因为它使用32位应用程序编写的配置,.NET软件将其注册表读取重定向到Win32 API应用程序实际写入的Wow6432Node。

没有任何应用程序正在运行提升。 所有应用程序都是交互式的。 用于运行应用程序的帐户具有对HKEY_LOCAL_MACHINE \ Software \\注册表项及其子项的明确“完全控制”。

据我所知,这不是使用注册表虚拟化,因为32位应用程序有写访问他们写到HKLM键。

此方案在64位Windows 7和64位Windows 8计算机上工作得很好,但在新的Windows 8.1 64位计算机上都不工作。

虽然传统的Win32应用程序写入注册表没有错误,它现在似乎正在虚拟化。这可以通过查看用户虚拟化注册表项来确认;我看到里面所有的书面价值。

当我使用REGEDIT查看HKEY_LOCAL_MACHINE \ Software \\键时,我写的大约一半的键只是从HKEY_LOCAL_MACHINE \ Software \\中丢失,但都存在于虚拟化文件夹中。

据我所知,它与32位应用程序写权限应该没有虚拟化,但有。更糟的是,当我读取非虚拟化密钥时,我看到一些但并非全部写入虚拟化商店的值。

为什么它突然虚拟化写入,为什么当读取原始密钥(即虚拟读取未按预期工作)时读取不显示所有虚拟值?

我认为这必须是一个权限问题,就好像我运行应用程序“作为管理员”的关键都在那里。然而,运行提升不是允许的最终配置。

更新

我清理了这台机器上的所有注册表设置。无论是HKCU下的虚拟商店还是HKLM下的共享区域。然后再次开始,没有升高。这导致了类似的症状,但是这次我只能看到HKLM密钥中的一个密钥。

我的打算写一个Win32应用程序来枚举HKEY_LOCAL_MACHINE \ SOFTWARE \\键的情况下,我正被一些REGEDIT.EXE所愚弄,或者在64位操作系统上运行,并且会更新时,是不是做对我来说我有结果。得到它与传统的32位WinAPI应用程序和新的64位应用程序之间的虚拟化不匹配。详情请参阅我的回答。

回答

3

注册表的虚拟化在Windows 8.1中的工作方式与在Vista,Win7和Win8中的工作方式完全相同。没有任何更改可以解释您报告的内容。

您是否知道7年前在Vista中引入了虚拟化技术,以帮助无法修改的应用程序在UAC上工作。这个想法是,你修复你的应用程序以了解UAC,并停止运行虚拟化。

关于虚拟化的一点是,如果以标准用户身份运行,应用程序将写入虚拟商店。但是,如果您执行提升的应用程序,则应用程序将写入注册表的共享部分HKLM。从上面的描述看来,您似乎已经运行了应用程序,并且已将值写入HKLM而不是虚拟商店。

我建议你清理掉这台机器上的所有注册表设置。在HKCU下的虚拟商店中以及在HKLM下的共享区域中。然后重新开始你的应用程序,而不是提升。我相信它会像以前的版本一样工作。

但是,我很惊讶你仍然在尝试使用虚拟化功能。这是一个帮助无助的拐杖。不要无奈。停止运行虚拟化。远离虚拟化。

更新

你的问题编辑改变了这种完全。事实上,你并没有问及Windows 8.1和早期版本之间的差异。您正在Windows 8.1机器上运行一个不同的程序,一个是64位。而64位进程永远不会虚拟化。

我再次重申我的建议,即虚拟化不会像你这样使用。依靠这种方式是愚蠢的。

+0

如果我有任何选择,我不会使用它,但发展需要时间和成本的钱,现在有一点爱花钱来修复“工作”的传统应用程序。 –

+0

我会尝试一下这个建议(我们的Windows 8 64位机器上的一切看起来都很好),看看它是否会将事情排序。 –

+2

事情是不行的。只要有人跑高架,一个扳手就会投入工作。您只需写信给HKCU而不是HKLM即可。 –

0

好吧,我已经到了这个底部。 David Heffernan说得对,过去这些应用程序的运行时间确实让水域变得非常混乱。

我写了一个小测试对应用程序的隔离问题(或者说非问题,因为它原来) 一个Delphi 6的32位的Win32应用程序,列举了HKEY_LOCAL_MACHINE \ SOFTWARE \\的关键,因为所有其他遗留应用程序做;即忽略密钥的虚拟化。这看起来好像在HKEY_LOCAL_MACHINE \ Software \\区域中的所有键,即使它们实际上已写入VirtualStore HKLU区域。这就解释了为什么我们所有的旧版应用都很开心。

我还写了一个简单的.NET 64位应用程序来测试它如何枚举HKEY_LOCAL_MACHINE \ Software \\键的注册表。注意到,无论查看模式(32位还是64位)。它确实看到了虚拟注册表位置中的所有内容。

我的问题是虚拟化的范围。它的传统应用程序。 Windows假定任何64位应用程序都不是传统应用程序,并且正在做正确的事情; 64位应用程序禁用读取虚拟化;如果你的64位应用程序必须读取操作系统为你虚拟化的传统32位应用程序编写的值,则必须自己动手。

有关详细信息,请参阅此MSDN文章;相关的位(我已经错过了)在题为“Registry Virtualization Scope

Registry virtualization is disabled for the following: 
•64-bit processes. 

我已经修改了我的新的应用占的事实,因为它必须中继上由传统的书面设置部分32位应用程序;这些设置可能会被虚拟化,因此它现在会在回退到未虚拟化之前检查虚拟化注册表位置。

+1

我回答了你问的问题。 64位应用程序未被虚拟化的这个问题是不同的,而不是问题。记住这个问题是关于8.1的变化。现在,说你上8.1运行不同的程序! –

0

我一直在困扰同一个问题,我没有使用64位应用程序。我们的应用程序是一个销售点软件,它使用注册表中的所有用户共用的密钥来存储有关业务应用程序的GLOBAL信息。我们继续进行的方式是,我们将HKLM/software/Store管理密钥和子密钥中的写入权限授予该密钥,以便应用程序不会虚拟到私人用户注册表中。存储在那里的财务和配置信息必须可供运行我们软件的任何用户使用。

最重要的是,我们使用reg flags命令来设置该键和子键上的dont_virtualize dont_silent_fail recurse_flag,以警告Windows停止虚拟化此键和子键。这在Vista和Windows 7上运行良好,但显然它在Windows 8.1上无法正常工作。显然我无论是随机抽取一些密钥。

所以在我的情况下,我不指望虚拟化使我的程序工作,而是我被它踢的时候,它不应该被搞砸了。我试图找到永久禁用此虚拟化的方法,因为我的程序不需要拐杖走路。

附录: 在寻找可能的解决方案时,我发现如果32位程序具有向Windows解释其与Vista和Windows 7兼容的程度的清单,则Windows将停止虚拟化常用注册表项,甚至会生成当用户没有适当的权限写入我们程序的公共注册表部分时,会出现预期的访问错误。因此,对于已经在该领域的版本,单独的清单文件将显然​​解决此问题,并且我们应该在我们的软件的新版本中嵌入清单。我们仍然会使用reg flags命令来要求Windows不要虚拟化密钥,并在未授予访问权限时给出错误,因为它应该总是首先完成。

相关问题