Windows Produkt-Key ermitteln mit C#

Seit Windows 8 hat Microsoft einiges am Product-Key, also der Seriennummer, die zum aktivieren des Betriebssystems notwendig ist, geändert. Zum einen wurde der Zeichenumfang, aus denen der Schlüssel besteht, erweitert und zum anderen braucht die Seriennummer größtenteils gar nicht mehr eingegeben werden, da sie im BIOS hinterlegt ist. Der Vorteil ist sicherlich, dass man bei einer Windows-Installation nicht mehr gezwungen ist, die 25-stellige Nummer einzutippen. Allerdings würde der Eine oder Andere doch ganz gerne seine Windows-Seriennummer kennen.

Alle, die ihr C#-Projekt mit einer Anzeige des Windows-Product-Keys erweitern wollen, finden hier den Quellcode von meiner Version zum auslesen und decodieren der Seriennummer:

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Win32;
 
namespace GetWindowsProductKey
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private static string GetProductKey()
        {
            RegistryKey BaseKey = default(RegistryKey);
            RegistryKey SubKey = default(RegistryKey);
            if (Environment.Is64BitOperatingSystem == true)
            {
                BaseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
                SubKey = BaseKey.OpenSubKey("SOFTWARE\\Microsoft\\Windows" + " NT\\CurrentVersion", false);
            }
            else
            {
                SubKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", false);
            }
            byte[] digitalProductId = (byte[])SubKey.GetValue("DigitalProductId", new byte[-1 + 1]);
            int keyStartIndex = 52;
            int keyEndIndex = keyStartIndex + 15;
            const int numLetters = 24;
            // Mögliche Alpha-Numerische Zeichen im Produkt-Schlüssel
            char[] digits = new char[]
            {
                'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R',
                'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9'
            };
            // Prüfen, ob es ein Windows 8/Office 2013-Schlüssel ist (Kann den Buchstaben 'N' enthalten)
            int containsN = (digitalProductId[keyStartIndex + 14] >> 3) & 1;
            digitalProductId[keyStartIndex + 14] = Convert.ToByte((digitalProductId[keyStartIndex + 14] & 0xf7) | ((containsN & 2) << 2));
            // Länge des decodierten Produkt-Schlüssels
            const int decodeLength = 29;
            // Länge des decodierten Schlüssels in Byte-Form
            // Jedes Byte repräsentiert 2 Zeichen
            const int decodeStringLength = 15;
            // Array, das den decodierten Produkt-Schlüssel enthält
            char[] decodedChars = new char[decodeLength];
            // Extrahiere Byte 52 bis 67 inklusive.
            List<byte> hexPid = new List<byte>();
            for (int i = keyStartIndex; i <= keyEndIndex; i++)
            {
                hexPid.Add(digitalProductId[i]);
            }
            for (int i = decodeLength - 1; i >= 0; i--)
            {
                // Jedes 6. Zeichen ist ein Trennzeichen
                if ((i + 1) % 6 == 0)
                {
                    decodedChars[i] = '-';
                }
                else
                {
                    // Die eigentliche Decodierung
                    int digitMapIndex = 0;
                    for (int j = decodeStringLength - 1; j >= 0; j--)
                    {
                        int byteValue = (digitMapIndex << 8) | hexPid[j];
                        hexPid[j] = (byte)(byteValue / numLetters);
                        digitMapIndex = byteValue % numLetters;
                        decodedChars[i] = digits[digitMapIndex];
                    }
                }
            }
            // Erstes Zeichen entfernen und 'N' an die richtige Stelle setzen
            if (containsN != 0)
            {
                int firstLetterIndex = 0;
                for (int index = 0; index < numLetters; index++)
                {
                    if (decodedChars[0] != digits[index]) continue;
                    firstLetterIndex = index;
                    break;
                }
                string keyWithN = new string(decodedChars);
                keyWithN = keyWithN.Replace("-", string.Empty).Remove(0, 1);
                keyWithN = keyWithN.Substring(0, firstLetterIndex) + "N" +
                                keyWithN.Remove(0, firstLetterIndex);
                keyWithN = keyWithN.Substring(0, 5) + "-" + keyWithN.Substring(5, 5) + "-" +
                                keyWithN.Substring(10, 5) + "-" + keyWithN.Substring(15, 5) + "-" +
                                keyWithN.Substring(20, 5);
                return keyWithN;
            }
            return new string(decodedChars);
        }
    }
}

Die Funktion lässt sich in jedes Projekt integrieren und mit GetProductKey() aufrufen. Als Rückgabewert erhaltet Ihr einen String mit dem Produkt-Schlüssel. Zur Fehlerfreien Ausführung benötigt Ihr mindestens das .NET-Framework 4.0. Die Windows Product-Keys von Windows Vista, 7, 8, 8.1 und 10 werden korrekt angezeigt.

Schreibe einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Pflichtfelder sind mit * markiert.

Beitragskommentare