如何删除 64 位注册表键/值 (.NET 3.5)
如何在 .NET 3.5 及更低版本中从 32 位构建的应用程序访问 64 位注册表键
引言
本技巧展示了如何在 .NET 3.5 及更低版本中从 32 位构建的应用程序访问(仅删除)64 位注册表键/值。例如,为了从以下注册表项“HKEY_LOCAL_MACHINE\Software\Sample”中删除注册表键“Sample”,从 32 位应用程序将无法实现,因为由于注册表反射,打开以进行删除的注册表将是“HKEY_LOCAL_MACHINE\Software\Wow6432Node\Sample”。这是 Microsoft 在 64 位操作系统上反映不同注册表节点的方式。
操作系统类型 | 应用程序构建 | 注册表视图 | 要访问 64 位注册表 |
64 位 | 32 位 | 32 位 | 禁用注册表反射 |
64 位 | 64 位 | 64 位 | 不适用 |
示例项目包括一组互操作函数,并使用本机 Win32 注册表 API 来禁用注册表反射,以便 32 位构建的应用程序可以访问 64 位注册表键。
背景
在开发自定义应用程序时,我遇到了删除 64 位注册表项的情况。该应用程序有严格的约束:目标平台必须是“X86”构建,并且 .NET Framework 是 3.5 版本。我相信你们中的许多人都知道无法从构建为 32 位应用程序类型的应用程序中删除 64 位注册表项(有关注册表重定向的更多信息,请阅读此 MSDN 文章)。我们必须使用本机 Win32 API 注册表方法才能实现这一点。但是,在 .NET 4 中,有一种直接的方法可以实现这一点,因为 Registry 类已扩展为支持这一点。PInvoke 支持非常好,但它们仅适用于单个方法,并且没有提供一个简单但详细的示例来执行此操作。示例代码已在以下操作系统上进行了测试:Windows XP 64 位、Windows 7 64 位。
Using the Code
示例项目中有两个主要类
RegistryInterop
- 其中包含主要的 Win32 注册表互操作方法X64RegistryKey
- 类,其中包含用于打开、枚举、删除和关闭 64 位注册表键/值的方法。此类派生自IDisposable
,以便在Dispose()
方法中,可以使用RegistryInterop
关闭所有已打开的本机句柄。
用户必须创建 X64RegistryKey
类的实例,才能从 32 位应用程序读取、枚举或删除任何 64 位注册表键。
注意:此处未涵盖确定应用程序是否在 64 位/32 位操作系统上运行的逻辑,因为它不符合目的。 有很多在线文章详细讨论了这一点,CodeProject 就是其中之一。 示例项目假定代码将在 64 位计算机上执行。
// Delete a subkey (a registry tree) from HKEY_LOCAL_MACHINE
private void DeleteKey(string subkey)
{
// Open HKEY_LOCAL_MACHINE
using (X64RegistryKey basekey =
new X64RegistryKey(RegistryInterop.HKEY_LOCAL_MACHINE))
{
UIntPtr key = UIntPtr.Zero;
if (X64RegistryKey.SUCCESS == basekey.Open(subkey, out key))
// open the subkey under HKEY_LOCAL_MACHINE\subkey to delete it
{
using (X64RegistryKey regkey = new X64RegistryKey(key))
{
// call this method to disable registry reflection,
// so that the 64bit registry can be deleted
regkey.DisableReflection();
regkey.RegDeleteValue(Value);
}
}
}
}
关注点
对于文件和文件夹,也有一个类似的概念,称为文件重定向,其中 32 位应用程序将无法访问特定的文件和文件夹 64 位操作系统。 例如,如果 32 位应用程序查询环境变量 %PROGRAMFILES%
,则返回的值将为“c:\program files <x86>”,因为这是在 64 位操作系统上运行的 32 位应用程序的等效程序文件文件夹。 我将推出另一篇文章来展示如何禁用文件重定向。 对于大多数互操作函数,我广泛依赖 http://www.pinvoke.net/。 该站点提供了各种各样的互操作方法,并且具有一些非常好的支持示例代码。 另请检查 MSDN 上的注册表反射。
历史
- 首次更新:2012 年 7 月 21 日。