Es gibt immer noch die native Unterstützung für Zugriff auf die Registry unter 64 - Bit - Windows mit .NET Framework 4.x . Der folgende Code wird mit Windows 7, 64 Bit und auch mit Windows 10, 64 Bit getestet .
Anstatt zu verwenden "Wow6432Node"
, wodurch ein Knoten emuliert wird, indem ein Registrierungsbaum einem anderen zugeordnet wird, sodass er dort virtuell angezeigt wird, können Sie Folgendes tun:
Entscheiden Sie, ob Sie auf die 64-Bit- oder die 32-Bit-Registrierung zugreifen müssen, und verwenden Sie sie wie unten beschrieben. Sie können auch den später erwähnten Code verwenden (Abschnitt "Zusätzliche Informationen"), mit dem eine Vereinigungsabfrage erstellt wird, um Registrierungsschlüssel von beiden Knoten in einer Abfrage abzurufen. Sie können sie also weiterhin unter Verwendung ihres tatsächlichen Pfads abfragen.
64-Bit-Registrierung
Um auf die 64-Bit-Registrierung zuzugreifen , können Sie RegistryView.Registry64
Folgendes verwenden:
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();
localKey.Close();
}
Console.WriteLine(String.Format("RegisteredOrganization [value64]: {0}",value64));
32-Bit-Registrierung
Wenn Sie auf die 32-Bit-Registrierung zugreifen möchten , verwenden Sie RegistryView.Registry32
Folgendes:
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();
localKey32.Close();
}
Console.WriteLine(String.Format("RegisteredOrganization [value32]: {0}",value32));
Seien Sie nicht verwirrt, beide Versionen verwenden Microsoft.Win32.RegistryHive.LocalMachine
als ersten Parameter. Sie unterscheiden anhand des zweiten Parameters ( versus ), ob 64-Bit oder 32-Bit verwendet werden soll .RegistryView.Registry64
RegistryView.Registry32
Beachten Sie das
HKEY_LOCAL_MACHINE\Software\Wow6432Node
Enthält unter 64-Bit- Windows Werte, die von 32-Bit-Anwendungen verwendet werden, die auf dem 64-Bit-System ausgeführt werden. Nur echte 64-Bit-Anwendungen speichern ihre Werte HKEY_LOCAL_MACHINE\Software
direkt in. Der Teilbaum Wow6432Node
ist für 32-Bit-Anwendungen vollständig transparent. 32-Bit-Anwendungen sehen immer noch so aus, HKEY_LOCAL_MACHINE\Software
wie sie es erwarten (es handelt sich um eine Art Umleitung). In älteren Windows-Versionen sowie 32-Bit-Windows 7 (und Vista 32-Bit) ist der Teilbaum Wow6432Node
offensichtlich nicht vorhanden.
Aufgrund eines Fehlers in Windows 7 (64 Bit) gibt die 32-Bit-Quellcodeversion immer "Microsoft" zurück, unabhängig davon, welche Organisation Sie registriert haben, während die 64-Bit-Quellcodeversion die richtige Organisation zurückgibt.
Gehen Sie wie folgt vor, um auf den 64-Bit-Zweig zuzugreifen:
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");
Zusätzliche Informationen - für den praktischen Gebrauch:
Ich möchte einen interessanten Ansatz hinzufügen, den Johny Skovdal in den Kommentaren vorgeschlagen hat, den ich aufgegriffen habe, um mithilfe seines Ansatzes einige nützliche Funktionen zu entwickeln: In einigen Situationen möchten Sie alle Schlüssel zurückerhalten, unabhängig davon, ob es sich um 32-Bit oder handelt 64 Bit. Die SQL-Instanznamen sind ein solches Beispiel. In diesem Fall können Sie eine Vereinigungsabfrage wie folgt verwenden (C # 6 oder höher):
// using Microsoft.Win32;
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);
}
public static IEnumerable<string> GetRegKeyNames(RegistryView view, string regPath,
RegistryHive hive = RegistryHive.LocalMachine)
{
return RegistryKey.OpenBaseKey(hive, view)
?.OpenSubKey(regPath)?.GetSubKeyNames();
}
public static IEnumerable<string> GetAllRegKeyNames(string RegPath,
RegistryHive hive = RegistryHive.LocalMachine)
{
var reg64 = GetRegKeyNames(RegistryView.Registry64, RegPath, hive);
var reg32 = GetRegKeyNames(RegistryView.Registry32, RegPath, hive);
var result = (reg64 != null && reg32 != null) ? reg64.Union(reg32) : (reg64 ?? reg32);
return (result ?? new List<string>().AsEnumerable()).OrderBy(x => x);
}
Jetzt können Sie die obigen Funktionen einfach wie folgt verwenden:
Beispiel 1: SQL-Instanznamen abrufen
var sqlRegPath=@"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL";
foreach (var valueName in GetAllRegValueNames(sqlRegPath))
{
var value=GetRegValue(sqlRegPath, valueName);
Console.WriteLine($"{valueName}={value}");
}
gibt Ihnen eine Liste der Wertnamen und Werte in sqlRegPath.
Hinweis: Sie können auf den Standardwert einer Taste zugreifen (angezeigt vom Befehlszeilentool REGEDT32.EXE
als (Default)
), wenn Sie den ValueName
Parameter in den entsprechenden Funktionen oben weglassen .
Verwenden Sie die Funktion oder, um eine Liste der SubKeys in einem Registrierungsschlüssel abzurufen . Mit dieser Liste können Sie weitere Schlüssel in der Registrierung durchlaufen.GetRegKeyNames
GetAllRegKeyNames
Beispiel 2: Informationen zur Deinstallation der installierten Software abrufen
var currentVersionRegPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion";
var uninstallRegPath = $@"{currentVersionRegPath}\Uninstall";
var regKeys = Registry.GetAllRegKeyNames(RegPath: uninstallRegPath);
erhält alle 32-Bit- und 64-Bit-Deinstallationsschlüssel.
Beachten Sie die in den Funktionen erforderliche Nullbehandlung, da SQL Server als 32-Bit oder als 64-Bit installiert werden kann (Beispiel 1 oben). Die Funktionen sind überlastet, sodass Sie den 32-Bit- oder 64-Bit-Parameter bei Bedarf weiterhin übergeben können. Wenn Sie ihn jedoch weglassen, wird versucht, 64-Bit zu lesen. Wenn dies fehlschlägt (Nullwert), werden die 32-Bit-Werte gelesen.
Hier gibt es eine Besonderheit: Da sie GetAllRegValueNames
normalerweise in einem Schleifenkontext verwendet wird (siehe Beispiel 1 oben), gibt sie eine leere Aufzählung zurück, anstatt Schleifen null
zu vereinfachen foreach
: Wenn dies nicht so gehandhabt würde, müsste der Schleife ein Präfix vorangestellt werden eine if
Anweisungsprüfung, für null
die es umständlich wäre, dies zu tun - so dass dies einmal in der Funktion behandelt wird.
Warum sich um Null kümmern? Denn wenn es Sie nicht interessiert, werden Sie viel mehr Kopfschmerzen haben, wenn Sie herausfinden, warum diese Nullreferenzausnahme in Ihrem Code ausgelöst wurde - Sie würden viel Zeit damit verbringen, herauszufinden, wo und warum sie passiert ist. Und wenn es in der Produktion passiert ist, sind Sie sehr damit beschäftigt, Protokolldateien oder Ereignisprotokolle zu studieren (ich hoffe, Sie haben die Protokollierung implementiert) ... vermeiden Sie besser Nullprobleme, wenn Sie dies defensiv tun können. Die Bediener ?.
, ?[
... ]
und ??
können Ihnen sehr helfen (siehe den oben angegebenen Code). Es gibt einen schönen verwandten Artikel über die neuen nullbaren Referenztypen in C # , den ich zum Lesen empfehle, und auch diesen über den Elvis-Operator.
Tipp: Sie können die kostenlose Version von Linqpad verwenden , um alle Beispiele unter Windows zu testen. Es ist keine Installation erforderlich. Vergessen Sie nicht, auf der Registerkarte Namespace-Import zu drücken F4und einzugeben Microsoft.Win32
. In Visual Studio benötigen Sie using Microsoft.Win32;
oben in Ihrem Code.
Tipp: Um sich mit den neuen vertraut machen null Handhabung Betreiber , ausprobieren (und debug) den folgenden Code in LinqPad:
Beispiel 3: Demonstrieren von Nullbehandlungsoperatoren
static string[] test { get { return null;} } // property used to return null
static 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>"
}
Versuchen Sie es mit .Net Geige
Wenn Sie interessiert sind, habe ich hier einige Beispiele zusammengestellt, die zeigen, was Sie sonst noch mit dem Tool tun können.