104 votes

La lecture de 64 bits du Registre à partir d'une application 32 bits

J'ai un c# test de l'unité projet est compilé pour AnyCPU. Notre serveur de build est une machine 64 bits, et a un 64 bits de SQL Express instance installés.

Le projet de test utilise un code similaire à celui-ci pour identifier le chemin d'accès à l' .Les fichiers 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();
    }

Ce code fonctionne très bien sur notre 32bit postes de travail, et a fait un travail sur ok sur le serveur de build jusqu'à ce que j'ai récemment activé analyse de couverture de code avec NCover. Parce que NCover utilise 32 bits composant COM, le test runner (Gallion) s'exécute comme un processus 32 bits.

Vérification du registre, il n'y a pas de "Noms d'Instance" clé sous HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server

Est-il un moyen pour une application qui s'exécute en mode 32 bits pour accéder au registre à l'extérieur de Wow6432Node?

168voto

Matt Points 3445

Il y a encore de la prise en charge native pour les accès au registre en vertu de la 64 bits de Windows à l'aide .NET Framework 4.x. Le code suivant est testé avec Windows 7 64 bits. Pour accéder à la 64 bits du registre, vous pouvez utiliser:

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));

Si vous souhaitez accéder à la 32 bits de registre, utilisez:

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));

Ne pas confondre, les deux versions sont à l'aide de Microsoft.Win32.RegistryHive.LocalMachine comme premier paramètre, vous faites la distinction si l'utilisation de 64 bits ou 32 bits par le 2e paramètre (RegistryView.Registry64 contre RegistryView.Registry32).

Notez que

  • Sur un 64 bits de Windows, HKEY_LOCAL_MACHINE\Software\Wow6432Node contient des valeurs utilisées par les applications 32 bits en cours d'exécution sur le système 64 bits. Seul vrai 64 bits, les applications de stocker leurs valeurs en HKEY_LOCAL_MACHINE\Software directement. La sous-arborescence Wow6432Node est entièrement transparent pour les applications 32 bits, les applications 32 bits toujours voir l' HKEY_LOCAL_MACHINE\Software parce qu'ils attendent d'elle (c'est une sorte de redirection). Dans les anciennes versions de Windows ainsi que les 32 bits de Windows 7 (et Vista 32 bits) de la sous-arborescence Wow6432Node n'est évidemment pas exister.

  • En raison d'un bogue dans Windows 7 (64 bit), le 32 bits version du code source renvoie toujours "Microsoft" quelle que soit l'organisation que vous avez enregistrés et le 64 bits version du code source retourne le droit de l'organisation.

Revenir à l'exemple que vous avez fournies, le faire de la façon suivante pour accéder à la version 64 bits de la branche:

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");

Astuce: Vous pouvez utiliser Linqpad de tester tous les exemples sous Windows 7. Elle ne nécessite pas d'installation.

20voto

Stefan Points 29091

vous devez utiliser le KEY_WOW64_64KEY param lors de la création/d'ouverture de la clé de registre. Mais autant que je sache, ce n'est pas possible avec le Registre de la classe, mais seulement lors de l'utilisation de l'API directement.

Cela pourrait aider à obtenir vous avez commencé.

14voto

Mike Regan Points 916

J'ai trouvé ce post aujourd'hui sur la lecture de la 64 bits de registre à partir d'une application 32 bits. De loin la meilleure écriture-up que j'ai vu avec 3 exemples différents - j'ai utilisé la seconde avec une classe statique.

4voto

akira Points 3632

essayez ceci (à partir d'un processus 32 bits):

> %WINDIR%\sysnative\reg.exe query ...

(trouvé qu' ici).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X