Il existe toujours un support natif pour l'accès au registre sous Windows 64 bits en utilisant .NET Framework 4.x. Le code suivant est testé avec Windows 7, 64 bits et également avec Windows 10, 64 bits. Pour accéder au 64 registre de bits, 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 au Registre 32bit, 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 en utilisant Microsoft.Win32.RegistryHive.LocalMachine
comme premier paramètre, vous faites la distinction si utiliser 64 bits ou 32 bits par le 2e paramètre (RegistryView.Registry64
contre RegistryView.Registry32
).
Remarque que
Sur un Windows 64bit, 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. Seules les applications 64 bits authentiques stockent leurs valeurs directement dans HKEY_LOCAL_MACHINE\Software
.Le sous-arbre Wow6432Node
est entièrement transparent pour les applications 32 bits, les applications 32 bits voient toujours HKEY_LOCAL_MACHINE\Software
comme ils s'y attendent (c'est une sorte de redirection). Dans les anciennes versions de Windows ainsi que Windows 7 bits 32 bits (et 32 bits), le sous-arbre Wow6432Node
existe évidemment et non. En raison d'un bogue dans Windows 7 (64 bits), la version du code source 32 bits renvoie toujours «Microsoft» quelle que soit l'organisation que vous avez enregistrée alors que la version du code source 64 bits renvoie la bonne organisation.
Pour en revenir à l'exemple que vous avez fourni, faites-le de la manière suivante pour accéder à la branche 64 bits:
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");
Mise à jour:
I'D tiens à ajouter une approche intéressante Johny Skovdal a suggéré dans les commentaires, que j'ai ramassé pour développer des fonctions utiles en utilisant son approche: Dans certaines situations, vous wa nt pour récupérer toutes les clés, que ce soit 32 bits ou 64 bits. Les noms d'instance SQL sont un exemple. Vous pouvez utiliser une requête syndicale dans ce cas comme suit (C# 6 ou plus):
public static IEnumerable<string> GetRegValueNames(RegistryView view, string regPath,
RegistryHive hive = RegistryHive.LocalMachine)
{
return RegistryKey.OpenBaseKey(hive, view)
?.OpenSubKey(regPath)?.GetValueNames();
}
public static IEnumerable<string> GetAllRegValueNames(string RegPath,
RegistryHive hive = RegistryHive.LocalMachine)
{
var reg64 = GetRegValueNames(RegistryView.Registry64, RegPath, hive);
var reg32 = GetRegValueNames(RegistryView.Registry32, RegPath, hive);
var result = (reg64 != null && reg32 != null) ? reg64.Union(reg32) : (reg64 ?? reg32);
return (result ?? new List<string>().AsEnumerable()).OrderBy(x => x);
}
public static object GetRegValue(RegistryView view, string regPath, string ValueName,
RegistryHive hive = RegistryHive.LocalMachine)
{
return RegistryKey.OpenBaseKey(hive, view)
?.OpenSubKey(regPath)?.GetValue(ValueName);
}
public static object GetRegValue(string RegPath, string ValueName,
RegistryHive hive = RegistryHive.LocalMachine)
{
return GetRegValue(RegistryView.Registry64, RegPath, ValueName, hive)
?? GetRegValue(RegistryView.Registry32, RegPath, ValueName, hive);
}
Maintenant, vous pouvez simplement utiliser les fonctions ci-dessus comme suit:
var [email protected]"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL";
foreach (var valueName in GetAllRegValueNames(sqlRegPath))
{
var value=GetRegValue(sqlRegPath, valueName);
Console.WriteLine($"{valueName}={value}");
}
qui vous donnera une liste des noms de valeur et des valeurs dans sqlRegPath.
Notez la manipulation requis dans les fonctions car le serveur SQL peut être installé en tant que 32 bits ou 64 bits. Les fonctions sont surchargées de sorte que vous pouvez toujours passer le paramètre 32 bits ou 64 bits si nécessaire - cependant, si vous l'omettez, il essayera de lire 64 bits, si cela échoue (valeur nulle), il lit les valeurs de 32 bits.
Il y a une spécialité ici: Parce que GetAllRegValueNames
est habituellement utilisé dans un contexte de boucle (voir exemple ci-dessus), elle retourne un vide dénombrable plutôt que null
pour simplifier foreach
boucles: si elle ne serait pas traitée de cette façon, la boucle devrait être préfixée par une instruction if
vérifiant null
ce qui serait fastidieux de le faire - donc cela est traité une fois dans la fonction.
Pourquoi s'embêter avec null? Parce que si vous ne vous en souciez pas, vous aurez beaucoup plus de maux de tête à découvrir pourquoi cette exception de référence nulle a été lancée dans votre code - vous passeriez beaucoup de temps à trouver où et pourquoi c'est arrivé. Et si cela s'est produit en production, vous serez très occupé à étudier les fichiers journaux ou les journaux d'événements (j'espère que vous avez implémenté la journalisation) ... mieux éviter les problèmes nuls où vous le pouvez d'une manière défensive. Les opérateurs ?.
, ?[
... ]
et ??
peuvent vous aider beaucoup (voir le code ci-dessus).
Conseil: Vous pouvez utiliser la version gratuite de Linqpad pour tester tous les exemples sous Windows. Il ne nécessite pas d'installation.N'oubliez pas d'appuyer sur F4 et d'entrer Microsoft.Win32
dans l'onglet Importation de l'espace de noms. Dans Visual Studio, vous avez besoin de using Microsoft.Win32;
en haut de votre code.
Astuce: Pour vous familiariser avec les nouveaux opérateurs de manutention nuls , essayer (et debug) le code suivant dans LINQPad:
string[] test { get { return null;} } // property used to return null
void Main()
{
test.Dump(); // output: null
// "elvis" operator:
test?.Dump(); // output:
// "elvis" operator for arrays
test?[0].Dump(); // output:
(test?[0]).Dump(); // output: null
// combined with null coalescing operator (brackets required):
(test?[0]??"<null>").Dump(); // output: "<null>"
}
Si vous êtes intéressé, here sont quelques-uns exemples que j'ai mis ensemble montrant ce que vous pouvez faire d'autre avec l'outil.
Merci pour cette réponse complète. De mémoire je pense que j'utilisais .NET 3.5 quand j'ai posté la question, mais bon de voir .NET 4 a amélioré la situation –
De rien. J'ai récemment eu un problème similaire avec le registre 64 bits que j'avais déjà résolu et j'ai pensé qu'il valait la peine de partager la solution. – Matt
C'est exactement ce que je cherchais. Je fais cela dans Windows 9.1 et ça marche très bien. –