0

如果我对此有误,请纠正我,因为我确定我在某处读过它:Windows 服务已禁用注册表虚拟化。此外,对 x64 二进制文件禁用了虚拟化。

我有一个用 C# 编写的 Windows 服务,它需要从 HKEY_LOCAL_MACHINE\SOFTWARE 加载一个值。当我将服务编译为 x86 并启动它时,它无法读取该值。当我编译与 x64 相同的代码并启动它时,它读取的值就好了。除了 x64 机器之外,我希望我的服务能够在 x86 机器上运行,但它还需要能够读取此值。如何让我的 Windows 服务读取非虚拟化的值?

4

1 回答 1

1

Windows 服务禁用注册表虚拟化。此外,对 x64 二进制文件禁用了虚拟化。

是的,你是对的,它对 64 位进程和“非交互式进程,例如服务”被禁用。

有关注册表视图的一些详细信息,请查看我之前关于 SO 的帖子。请不要将视图虚拟化混淆。他们是不同的。需要使用视图将 32 位应用程序与 64 位应用程序隔离开来。

在 C# 中,您可以执行相同的操作,只需要求操作系统打开 64 位版本的注册表:

RegistryKey baseKey = RegistryKey.OpenBaseKey(
    RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey key = baseKey.OpenSubKey("Software", false);
object value = key.GetValue("");

如果您的应用程序/服务将在 32 位机器上运行,即使您要求RegistryView.Registry64. 在 64 位机器上运行时,您将始终获得注册表的正常版本(= 64 位版本)。

附带问题:为什么需要将应用程序编译为 X86 或 X64?不能简单地保留AnyCPU?

虚拟化有不同的目的,它并不是要将注册表与 32 位应用程序分开,而是为了增加与遗留应用程序的兼容性,我们都希望 64 位本机应用程序以正确的方式使用注册表。要访问注册表的非虚拟化版本,您必须使用REG_KEY_DONT_VIRTUALIZE标志打开注册表项。无法将此标志与Microsoft.Win32类一起使用,因此您必须使用DllImport它们和 P/Invoke。

于 2012-05-23T13:58:43.197 回答