Todavía hay soporte nativo para acceso al registro en Windows de 64 bits usando .NET Framework 4.x. El siguiente código se prueba con Windows 7, 64 bit y también con Windows 10, 64 bit. tener acceso al registro de 64 bits , puede utilizar:
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 desea tener acceso al registro de 32 bits , utilice:
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));
no se confunda, ambas versiones son usando Microsoft.Win32.RegistryHive.LocalMachine
como primer parámetro, se hace la distinción si se usa 64 bit o 32 bit por el 2do parámetro (RegistryView.Registry64
versus RegistryView.Registry32
).
Nota que
En un Windows de 64 bits, HKEY_LOCAL_MACHINE\Software\Wow6432Node
contiene valores utilizados por las aplicaciones de 32 bits que se ejecutan en el sistema de 64 bits. Solo las aplicaciones verdaderas de 64 bits almacenan sus valores en HKEY_LOCAL_MACHINE\Software
directamente.El subárbol Wow6432Node
es completamente transparente para aplicaciones de 32 bits, las aplicaciones de 32 bits aún ven HKEY_LOCAL_MACHINE\Software
como lo esperan (es una especie de redirección). En las versiones anteriores de Windows, así como en Windows 7 de 32 bits (y en Vista de 32 bits), el subárbol Wow6432Node
obviamente no contiene ni.
Debido a un error en Windows 7 (64 bit), la versión del código fuente de 32 bits siempre devuelve "Microsoft" independientemente de la organización que haya registrado mientras que la versión del código fuente de 64 bits devuelve la organización correcta.
Volviendo al ejemplo que nos ha facilitado, hacerlo de la siguiente manera de acceder a la rama 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");
Actualización:
que había Me gustaría añadir un enfoque interesante que Johny Skovdal ha sugerido en los comentarios, que he recogido para desarrollar algunas funciones útiles mediante el uso de su enfoque: En algunas situaciones, usted nt para recuperar todas las claves independientemente de si son 32 bits o 64 bits. Los nombres de instancia SQL son un ejemplo. Se puede utilizar una consulta de unión en este caso de la siguiente manera (C# 6 o superior):
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);
}
Ahora usted puede simplemente utilizar las funciones antes de la siguiente manera:
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}");
}
el cual le dará una lista de los nombres y valores de valor en sqlRegPath.
Observe que se requiere el manejo nulo en las funciones porque el servidor SQL se puede instalar como de 32 bits o como de 64 bits. Las funciones están sobrecargadas, por lo que puede pasar el parámetro de 32 bits o de 64 bits si es necesario. Sin embargo, si lo omite, intentará leer 64 bits, si eso falla (valor nulo), lee los valores de 32 bits.
Hay una especialidad aquí: Debido GetAllRegValueNames
se utiliza generalmente en un contexto de bucle (véase el ejemplo anterior), devuelve un vacío enumerable en lugar de null
para simplificar foreach
bucles: si no se maneja de esa manera, el bucle debería ir precedido por una declaración if
que compruebe null
, lo que sería engorroso tener que hacer eso, por lo que se trata una vez en la función.
¿Por qué molestarse por null? Porque si no te importa, tendrás muchos más dolores de cabeza al descubrir por qué esa excepción de referencia nula fue lanzada en tu código: pasarías mucho tiempo buscando dónde y por qué sucedió. Y si sucedió en producción, estarás muy ocupado estudiando archivos de registro o registros de eventos (espero que hayas implementado el registro) ... mejor evita los problemas nulos donde puedas de forma defensiva. Los operadores ?.
, ?[
... ]
y ??
pueden ayudarlo mucho (consulte el código provisto arriba).
Consejo: Puede usar la edición gratuita de Linqpad para probar todos los ejemplos en Windows. No requiere una instalación.No olvide presionar F4 e ingresar Microsoft.Win32
en la pestaña de importación del espacio de nombres. En Visual Studio, necesita using Microsoft.Win32;
en la parte superior de su código.
Consejo: a familiarizarse con los nuevos operadores de handling nulos, probar (y depuración) el siguiente código en 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 está interesado, here son algunos ejemplos que reuní para mostrar qué más puedes hacer con la herramienta.
Gracias por su exhaustiva respuesta. De memoria, creo que estaba usando .NET 3.5 cuando publiqué la pregunta, pero es bueno ver que .NET 4 ha mejorado la situación –
De nada. Recientemente tuve un problema similar con el registro de 64 bits que ya había resuelto, así que pensé que valía la pena compartir la solución. – Matt
Esto es exactamente lo que he estado buscando. Estoy haciendo esto en Windows 9.1 y funciona muy bien. –