从32位应用程序读取64位注册表

我有一个为AnyCPU编译的c#单元测试项目。我们的构建服务器是一个64位机器,并且安装了64位SQL Express实例。

测试项目使用与以下类似的代码来识别.MDF文件的路径:

    private string GetExpressPath()
    {
        RegistryKey sqlServerKey = Registry.LocalMachine.OpenSubKey( @"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL" );
        string sqlExpressKeyName = (string) sqlServerKey.GetValue( "SQLEXPRESS" );
        RegistryKey sqlInstanceSetupKey = sqlServerKey.OpenSubKey( sqlExpressKeyName + @"\Setup" );
        return sqlInstanceSetupKey.GetValue( "SQLDataRoot" ).ToString();
    }

此代码在我们的32位工作站上工作正常,并且在构建服务器上工作正常,直到我最近启用了与NCover的代码覆盖率分析。由于NCover使用32位COM组件,测试运行器(Gallio)以32位进程运行。

检查注册表,没有”Instance Names”键

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server

有没有办法在32位模式下运行的应用程序访问Wow6432Node之外的注册表?

最佳解决方案

在创建/打开注册表项时,必须使用KEY_WOW64_64KEY参数。但是,AFAIK对于注册表类是不可能的,但只能直接使用API​​。

This可能有助于您开始使用。

次佳解决方案

仍然使用.NET Framework 4.x在64位Windows下仍然支持注册表访问。以下代码通过Windows 7 64位进行测试。要访问64位注册表,可以使用:

string value64 = string.Empty; 
RegistryKey localKey = 
    RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, 
        RegistryView.Registry64); 
localKey = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion"); 
if (localKey != null) 
{ 
    value64 = localKey.GetValue("RegisteredOrganization").ToString(); 
} 
Console.WriteLine(String.Format("RegisteredOrganization [value64]: {0}",value64));

如果要访问32位注册表,请使用:

string value32 = string.Empty; 
RegistryKey localKey32 = 
    RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, 
        RegistryView.Registry32); 
localKey32 = localKey32.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion"); 
if (localKey32 != null) 
{ 
    value32 = localKey32.GetValue("RegisteredOrganization").ToString(); 
} 
Console.WriteLine(String.Format("RegisteredOrganization [value32]: {0}",value32));

不要混淆,两个版本都使用Microsoft.Win32.RegistryHive.LocalMachine作为第一个参数,您可以区分第二个参数(RegistryView.Registry64RegistryView.Registry32)是否使用64位或32位。

注意

  • 在64位Windows上,HKEY_LOCAL_MACHINE\Software\Wow6432Node包含在64位系统上运行的32位应用程序使用的值。只有真正的64位应用程序才能将它们的值直接存储在HKEY_LOCAL_MACHINE\Software中。子树Wow6432Node对于32位应用程序是完全透明的,32位应用程序依然看到HKEY_LOCAL_MACHINE\Software(它是一种重定向)。在旧版本的Windows以及32位Windows 7(和Vista 32位)中,子树Wow6432Node显然不存在。
  • 由于Windows 7(64位)中的错误,32位源代码版本始终返回”Microsoft”,无论您注册了哪个组织,而64位源代码版本返回正确的组织。

回到您提供的示例,使用以下方式访问64位分支:

RegistryKey localKey = 
    RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, 
        RegistryView.Registry64); 
RegistryKey sqlServerKey = localKey.OpenSubKey(
    @"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL");
string sqlExpressKeyName = (string) sqlServerKey.GetValue("SQLEXPRESS");

提示:您可以使用Linqpad来测试Windows 7下的所有示例。它不需要安装。

thedarkside

这是一个最好的时代,这是一个最坏的时代。

stay connected

228,480

Fans

21,563

Followers

20,563

Followers

8,125

Subscribers

2,253

Subscribers

10,563

Followers

最新文章

entertainment
Buckingham Palace soil used in Tate exhibit
Oct 13, 2016
Sports
Legendary coach Steve Spurrier was truly
Oct 13, 2016
Technology
Acer reveals all-in-one Windows 10 PC
Oct 13, 2016
entertainment
Revival allows Selena Gomez to shed
Oct 13, 2016
entertainment
Buckingham Palace soil used in Tate exhibit
Oct 13, 2016
Sports
Legendary coach Steve Spurrier was truly
Oct 13, 2016
Technology
Acer reveals all-in-one Windows 10 PC
Oct 13, 2016
entertainment
Revival allows Selena Gomez to shed
Oct 13, 2016