Aplicación completa en C# (C Sharp de Visual Studio .NET) que obtiene el product key (clave de producto) de un equipo Windows (cualquier versión Windows 7, W8, W10, W11 y Windows Server 2008, WS2012, WS2016, WS2019 y WS2022). La aplicación permite decodificar claves hexadecimales de otros equipos. Incluimos enlace para la descarga del código fuente completo y el ejecutable de la aplicación ProyectoA Obtener Product Key de Windows.
- Formularios y componentes necesarios para el desarrollo de la aplicación C# ProyectoA Obtener Product Key de Windows.
- Código fuente de cada componente en C#.
- Aplicación ProyectoA Obtener Product Key de Windows en funcionamiento.
- Descarga de la aplicación completa (incluye código fuente y ejecutable).
Formularios y componentes necesarios para el desarrollo de la aplicación C# ProyectoA Obtener Product Key de Windows
Para el desarrollo de la aplicación ProyectoA Obtener Product Key de Windows se ha usado un formulario principal, con los siguiente componentes:
- formKey.cs: formulario principal (ventana de inicio de la aplicación), para obtener la clave de producto del equipo actual. Con los siguientes componentes:
- formDecodificar.cs: formulario para decodificar otras claves obtenidas en otros equipos. Solicitará al usuario que introduzca el valor hexadecimal de la clave de producto y lo decodificará, para mostrarlo de forma legible. Con los siguientes componentes:
- Decodificar.cs: clase que contiene los métodos para obtener los valores de las claves de registro y para decodificarlos.
Código fuente de cada componente en C#
A continuación, mostramos el código fuente completo de cada formulario y de la clase Decodificar.cs.
Formulario principal formKey.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
using System; using System.Windows.Forms; namespace ProductKeyWindowsProyectoA { public partial class formKey : Form { public formKey() { InitializeComponent(); } private void btnFromProductKey_Click(object sender, EventArgs e) { var form = new formDecodificar(); form.ShowDialog(); } private void btCopiarDigitalProductID_Click(object sender, EventArgs e) { // Seleccionamos la clave obtenida txtKeyDigitalProductId.SelectionStart = 0; txtKeyDigitalProductId.SelectionLength = txtKeyDigitalProductId.Text.Length; // Copiamos al portapapeles txtKeyDigitalProductId.Copy(); } private void btObtenerKeyDigitalProductId_Click(object sender, EventArgs e) { // Obtenemos el valor de la clave de registro // Equipo\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId // Lo decodificamos para mostrarlo en caracteres legibles txtKeyDigitalProductId.Text = Decodificar.ObtenerProductKeyRegistro(false, false); } private void button1_Click(object sender, EventArgs e) { // Obtenemos el valor de la clave de registro // Equipo\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId4 // Lo decodificamos para mostrarlo en caracteres legibles txtKeyDigitalProductId4.Text = Decodificar.ObtenerProductKeyRegistro(true, false); } private void btCopiarDigitalProduct4_Click(object sender, EventArgs e) { // Seleccionamos la clave obtenida txtKeyDigitalProductId4.SelectionStart = 0; txtKeyDigitalProductId4.SelectionLength = txtKeyDigitalProductId4.Text.Length; // Copiamos al portapapeles txtKeyDigitalProductId4.Copy(); } private void btnClose_Click(object sender, EventArgs e) { Application.Exit(); } } } |
Formulario formDecodificar.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
using System; using System.Linq; using System.Windows.Forms; namespace ProductKeyWindowsProyectoA { public partial class formDecodificar : Form { public formDecodificar() { InitializeComponent(); } private void btnClearDigitalProductId_Click(object sender, EventArgs e) { txtValorHex.Clear(); txtProductKey.Clear(); txtHexadecimalFormateado.Clear(); } private void tbDigitalProductId_TextChanged(object sender, EventArgs e) { txtProductKey.Clear(); txtHexadecimalFormateado.Clear(); } private void DigitalProductIdForm_Load(object sender, EventArgs e) { lsSO.SelectedIndex = 1; } private void btnCopyToClipboard_Click(object sender, EventArgs e) { // Seleccionamos la clave obtenida txtProductKey.SelectionStart = 0; txtProductKey.SelectionLength = txtProductKey.Text.Length; // Copiamos al portapapeles txtProductKey.Copy(); } private void btnParseDigitalProductId_Click(object sender, EventArgs e) { if (txtValorHex.Text == "") { MessageBox.Show("Introduzca el valor hexadecimal obtenido de la clave de registro para decodificar.", "Faltan datos para decodificar...", MessageBoxButtons.OK, MessageBoxIcon.Information); txtValorHex.Focus(); } else { try { string valorFormatear = txtValorHex.Text.ToLower(); // Si se ha introducido "DigitalProductId4"= lo quitamos valorFormatear = valorFormatear.Replace("digitalproductid4", "").Replace("\"", "").Replace("=", ""); // Si se ha introducido "DigitalProductId"= lo quitamos valorFormatear = valorFormatear.Replace("digitalproductid", "").Replace("\"", "").Replace("=", ""); // Elimininamos posibles saltos de línea, espacios y guiones valorFormatear = valorFormatear.Replace("\\\r\n", "").Replace(" ", "").Replace("-", ",").Trim(); // Añadimos "hex:" delante si no se ha añadido if (!valorFormatear.StartsWith("hex:", StringComparison.InvariantCultureIgnoreCase)) valorFormatear = "hex:" + valorFormatear; // Convertimos los valores hexadecimales de cadenas delimitadas por comas en una matriz de bytes var valorHexadecimal = valorFormatear.Remove(0, 4).Split(','); txtHexadecimalFormateado.Text = valorFormatear; // Creamos una matriz de bytes a partir de valores hexadecimales var valoresByte = valorHexadecimal.Select(s => Convert.ToByte(s.ToUpper(), 16)).ToArray(); txtProductKey.Text = Decodificar.GetWindowsProductKeyFromDigitalProductId( valoresByte, lsSO.SelectedIndex == 0 ? VersionDigitalProductID.hastaWindows7 : VersionDigitalProductID.Windows8EnAdelante); } catch (Exception) { string mensaje = "Error al decodificar la cadena. Recuerde que debe ser una cadena hexadecimal, " + "obtenida de la exportación de la clave de registro: " + Environment.NewLine + "Equipo\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\DigitalProductId"; MessageBox.Show(mensaje, "Error al decodificar...", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } } private void btObtenerDPId_Click(object sender, EventArgs e) { // Obtenemos el valor de la clave de registro // Equipo\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId // Lo decodificamos para mostrarlo en caracteres legibles txtValorHex.Text = Decodificar.ObtenerProductKeyRegistro(false, true); } private void btObtenerDPId4_Click(object sender, EventArgs e) { // Obtenemos el valor de la clave de registro // Equipo\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId4 // Lo decodificamos para mostrarlo en caracteres legibles txtValorHex.Text = Decodificar.ObtenerProductKeyRegistro(true, true); } private void btCopiarHex_Click(object sender, EventArgs e) { // Seleccionamos el hexadecimal obtenido txtHexadecimalFormateado.SelectionStart = 0; txtHexadecimalFormateado.SelectionLength = txtHexadecimalFormateado.Text.Length; // Copiamos al portapapeles txtHexadecimalFormateado.Copy(); } private void btCerrar_Click(object sender, EventArgs e) { Close(); } } } |
Clase Decodificar.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
using Microsoft.Win32; using System; using System.Collections; namespace ProductKeyWindowsProyectoA { // Para versiones de Windows 7 o inferiores o Windows 8 o superiores public enum VersionDigitalProductID { // Versiones Windows 7 o inferiores hastaWindows7, // Versiones Windows 8 o superiores Windows8EnAdelante } public static class Decodificar { public static string ObtenerProductKeyRegistro(bool DigitalProductId4, bool obtenerSoloValorHex) { var claveRegistroLM = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32); var valorRegistro = claveRegistroLM.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion")?.GetValue("DigitalProductId"); if (DigitalProductId4) valorRegistro = claveRegistroLM.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion")?.GetValue("DigitalProductId4"); if (valorRegistro == null) if (DigitalProductId4) return "Error al obtener la clave de registro DigitalProductId4"; else return "Error al obtener la clave de registro DigitalProductId"; var valorClaveDigitalProductID = (byte[])valorRegistro; if (!obtenerSoloValorHex) { claveRegistroLM.Close(); // Obtenemos la versión de Windows del equipo para aplicar un método u otro de decodificación var esWindows8OSuperior = Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 2 || Environment.OSVersion.Version.Major > 6; return GetWindowsProductKeyFromDigitalProductId(valorClaveDigitalProductID, esWindows8OSuperior ? VersionDigitalProductID.Windows8EnAdelante : VersionDigitalProductID.hastaWindows7); } else return BitConverter.ToString(valorClaveDigitalProductID); } public static string GetWindowsProductKeyFromDigitalProductId(byte[] digitalProductId, VersionDigitalProductID digitalProductIdVersion) { var productKey = digitalProductIdVersion == VersionDigitalProductID.Windows8EnAdelante ? DecodificarProductKeyWindows8EnAdelante(digitalProductId) : DecodificarProductKeyHastaWindows7(digitalProductId); return productKey; } private static string DecodificarProductKeyHastaWindows7(byte[] digitalProductId) { const int inicioKey = 52; const int finKey = inicioKey + 15; var digits = new[] { 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R', 'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9', }; const int longitudDecodificar = 29; const int longitudCadenaDecodificar = 15; var caracteresDecodificados = new char[longitudDecodificar]; var hexPid = new ArrayList(); for (var i = inicioKey; i <= finKey; i++) { hexPid.Add(digitalProductId[i]); } for (var i = longitudDecodificar - 1; i >= 0; i--) { // Cada sexto carácter es un separador if ((i + 1) % 6 == 0) { caracteresDecodificados[i] = '-'; } else { // Decodificamos var digitMapIndex = 0; for (var j = longitudCadenaDecodificar - 1; j >= 0; j--) { var byteValue = (digitMapIndex << 8) | (byte)hexPid[j]; hexPid[j] = (byte)(byteValue / 24); digitMapIndex = byteValue % 24; caracteresDecodificados[i] = digits[digitMapIndex]; } } } return new string(caracteresDecodificados); } public static string DecodificarProductKeyWindows8EnAdelante(byte[] digitalProductId) { var key = String.Empty; const int desplazaKey = 52; var esWindows8 = (byte)((digitalProductId[66] / 6) & 1); digitalProductId[66] = (byte)((digitalProductId[66] & 0xf7) | (esWindows8 & 2) * 4); const string digitos = "BCDFGHJKMPQRTVWXY2346789"; var ultimo = 0; for (var i = 24; i >= 0; i--) { var actual = 0; for (var j = 14; j >= 0; j--) { actual = actual*256; actual = digitalProductId[j + desplazaKey] + actual; digitalProductId[j + desplazaKey] = (byte)(actual/24); actual = actual%24; ultimo = actual; } key = digitos[actual] + key; } var key1 = key.Substring(1, ultimo); var key2 = key.Substring(ultimo + 1, key.Length - (ultimo + 1)); key = key1 + "N" + key2; for (var i = 5; i < key.Length; i += 6) { key = key.Insert(i, "-"); } return key; } } } |
Aplicación ProyectoA Obtener Product Key de Windows en funcionamiento
Iniciaremos el ejecutable (se encuentra en la carpeta:
…\ProyectoA_Obtener_Product_Key_Windows_CSharp\ObtenerProductKeyWindows\bin\Release
El ejecutable es: ProductKeyWindowsProyectoA.exe
En la ventana de inicio, pulsaremos en «Obtener» en la sección «Key en DigitalProductID» para obtener la clave de producto del equipo actual:
Si queremos obtener la clave de producto de DigitalProductId4, pulsaremos en el botón «Obtener» correspondiente:
Podremos copiar al portapapeles ambas claves, pulsando en el botón «Copiar» correspondiente.
Para decodificar claves en hexadecimal obtenidas de la exportación de la clave de registro:
1 |
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId |
Pulsaremos en «Decodificar otras claves». Nos mostrará una nueva ventana, pegaremos el valor hexadecimal obtenido de la exportación de la clave de registro y valor binario «DigitalProductId» o bien «DigitalProductId4» [1]. Elegiremos la versión de Windows (Windows 7 o inferior o bien Windows 8 o superior) [2] y pulsaremos en «Decodificar» [3]. Nos obtendrá la clave de producto según el hexadecimal indicado [5]:
Desde esta ventana podremos obtener las claves de producto para DigitalProductId y para DigitalProductId4 del equipo actual, pulsando en los botones «Obtener DPId equipo» o «Obtener DPId4 equipo». También nos mostrará el valor hexadecimal formateado que se utiliza para decodificar y obtener la clave.
Descarga de la aplicación completa (incluye código fuente y ejecutable)
A continuación, mostramos enlace para la descarga de la aplicación completa, incluyendo el código fuente en C# y el ejecutable para poder usarla en cualquier equipo: