No olvides que en las ciencias informáticas cualquier problema casi siempre tiene diversas resoluciones, así que aquí compartiremos la mejor y más eficiente.
Solución:
Como ya han señalado otras personas, se supone que no debe obtener ese valor directamente del registro (que probablemente sea la razón por la que no funciona de manera confiable entre las diferentes versiones de Windows).
Un poco de búsqueda me llevó al Win32_OperatingSystem
Clase WMI. Con esta clase, puede obtener el número de serie de Windows. Me tomó un poco de búsqueda y experimentación para hacerlo bien, pero así es como se usa en C #.
Asegúrate de tener el System.Management.dll
referencia en su proyecto:
using System.Management;
...
ManagementObject os = new ManagementObject("[email protected]");
string serial = (string)os["SerialNumber"];
Utilizando el []
operador, puede obtener cualquier propiedad de la clase.
que es probablemente la razón por la que no funciona de manera confiable entre diferentes versiones de Windows
No, esa no es la razón. Este problema se debe a la selección de destino de la plataforma para su proyecto EXE. Proyecto + Propiedades, pestaña Crear, cuadro combinado de destino de plataforma. Lo tiene configurado en x86 en lugar de AnyCPU. En VS2012, la casilla de verificación “Preferir 32 bits” es importante. Esta configuración obliga a su programa a ejecutarse en modo de 32 bits en una versión de Windows de 64 bits. Lo que tiene una serie de efectos secundarios, el que importa aquí es que el acceso al registro keys son redirigidos. Su programa en realidad está leyendo el valor de HKEY_LOCAL_MACHINE SOFTWARE Wow6432Node Microsoft Cryptography MachineGuid. Que no existe.
La selección x86 es la predeterminada para VS2010 y versiones posteriores, anteriormente AnyCPU era la predeterminada. Microsoft prefiere x86, Visual Studio funciona mejor con procesos en modo de 32 bits. Particularmente cuando se depura, VS es un proceso de 32 bits en sí mismo, por lo que requiere el depurador remoto si su programa se ejecuta en modo de 64 bits. Que tiene algunas limitaciones como no es compatible. mixed-modo de depuración. Y la función Editar + Continuar solo funciona para código de 32 bits. Sin embargo, su programa en sí funciona “mejor” si tiene la configuración en AnyCPU, lo que incluye no ser mordido por el sistema de archivos y las funciones de aplicación de redirección del registro integradas en Windows.
Si realmente está atascado con el modo x86, generalmente porque tiene una dependencia en el código nativo de 32 bits que no puede actualizar, la siguiente solución es usar el método .NET 4+ RegistryKey.OpenBaseKey (). Lo que le permite pasar RegistryView.Registry64, asegurándose de que leerá los archivos no redirigidos. keys.
Claro, usar WMI es una solución. Solo ten en cuenta que eres no leer la misma información cuando usa Win32_OperatingSystem.SerialNumber. En que grado eso key es confiablemente aleatorio en diferentes máquinas no es tan claro para mí, solo digamos que este valor es un objetivo bastante atractivo para el tipo de usuarios que tampoco están muy interesados en pagar la tarifa de licencia de su producto.
Por último, pero no menos importante, tenga en cuenta que es bastante fácil generar su propia identificación única que no depende en absoluto de Windows. Con la considerable ventaja de que no enojará a su cliente cuando actualice Windows en su máquina. Simplemente use Guid.NewGuid () una vez y almacene el valor en un archivo. Eso se perderá cuando la unidad se estropee, pero eso generalmente también elimina su producto.
Yo, mi humilde opinión, ninguna de las respuestas satisface la pregunta; Es bastante sencillo pedir una forma de leer MachineGuid desde el registro … así que aquí está mi respuesta: Deberá agregar una referencia a “Microsoft.Win32”. Este código se escribió con fines de demostración y debe adaptarse en consecuencia.
EDITAR: Alguien dijo erróneamente que el código x64 es inútil.
En el sistema operativo de 64 bits, ahí es donde key es encontrado.
Entonces, esta respuesta es la única que satisface la pregunta.
private void buttonGetMachineGuid_Click(object sender, RoutedEventArgs e)
try
string x64Result = string.Empty;
string x86Result = string.Empty;
RegistryKey keyBaseX64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey keyBaseX86 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
RegistryKey keyX64 = keyBaseX64.OpenSubKey(@"SOFTWAREMicrosoftCryptography", RegistryKeyPermissionCheck.ReadSubTree);
RegistryKey keyX86 = keyBaseX86.OpenSubKey(@"SOFTWAREMicrosoftCryptography", RegistryKeyPermissionCheck.ReadSubTree);
object resultObjX64 = keyX64.GetValue("MachineGuid", (object)"default");
object resultObjX86 = keyX86.GetValue("MachineGuid", (object)"default");
keyX64.Close();
keyX86.Close();
keyBaseX64.Close();
keyBaseX86.Close();
keyX64.Dispose();
keyX86.Dispose();
keyBaseX64.Dispose();
keyBaseX86.Dispose();
keyX64 = null;
keyX86 = null;
keyBaseX64 = null;
keyBaseX86 = null;
if(resultObjX64 != null && resultObjX64.ToString() != "default")
MessageBox.Show(resultObjX64.ToString());
if(resultObjX86 != null && resultObjX86.ToString() != "default")
MessageBox.Show(resultObjX86.ToString());
catch(Exception)
Espero que esto ayude a alguien.
Eres capaz de añadir valor a nuestra información dando tu experiencia en las críticas.