簡體   English   中英

如何在 C# 中獲取 Windows XP 產品密鑰?

[英]How can I get windows XP product key in C#?

如何在 C# 中獲取 Windows XP 產品密鑰?

我想從客戶端獲取一些像 Windows 鍵這樣的鍵。

Windows Product Key Finder 和 Erij J. 和其他人在此提到的其他解決方案僅適用於 Windows XP 和 Windows 7。 自 Windows 8 起,Microsoft 更改了密鑰加密算法。

我在這里的博客文章中找到了適用於 Windows 8 及更高版本的解決方案: http ://winaero.com/blog/how-to-view-your-product-key-in-windows-10-windows-8-and-windows -7/

但是它是用 VBS 編寫的,所以我將它重寫為 C#。

你可以在 GitHub 上查看完整的項目: https : //github.com/mrpeardotnet/WinProdKeyFinder

以下是如何在 Windows 8 及更高版本中解碼產品密鑰的代碼:

    public static string DecodeProductKeyWin8AndUp(byte[] digitalProductId)
    {
        var key = String.Empty;
        const int keyOffset = 52;
        var isWin8 = (byte)((digitalProductId[66] / 6) & 1);
        digitalProductId[66] = (byte)((digitalProductId[66] & 0xf7) | (isWin8 & 2) * 4);

        // Possible alpha-numeric characters in product key.
        const string digits = "BCDFGHJKMPQRTVWXY2346789";
        int last = 0;
        for (var i = 24; i >= 0; i--)
        {
            var current = 0;
            for (var j = 14; j >= 0; j--)
            {
                current = current*256;
                current = digitalProductId[j + keyOffset] + current;
                digitalProductId[j + keyOffset] = (byte)(current/24);
                current = current%24;
                last = current;
            }
            key = digits[current] + key;
        }
        var keypart1 = key.Substring(1, last);
        const string insert = "N";
        key = key.Substring(1).Replace(keypart1, keypart1 + insert);
        if (last == 0)
            key = insert + key;
        for (var i = 5; i < key.Length; i += 6)
        {
            key = key.Insert(i, "-");
        }
        return key;
    }

要檢查 Windows 版本並獲取 digitalProductId 使用如下包裝方法:

    public static string GetWindowsProductKey()
    {
            var key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
                                          RegistryView.Default);
            const string keyPath = @"Software\Microsoft\Windows NT\CurrentVersion";
            var digitalProductId = (byte[])key.OpenSubKey(keyPath).GetValue("DigitalProductId");

        var isWin8OrUp =
            (Environment.OSVersion.Version.Major == 6 && System.Environment.OSVersion.Version.Minor >= 2)
            ||
            (Environment.OSVersion.Version.Major > 6);

        var productKey = isWin8OrUp ? DecodeProductKeyWin8AndUp(digitalProductId) : DecodeProductKey(digitalProductId);
        return productKey;
    }

我已經在多台機器上測試過它,它給了我正確的結果。 即使在 Windows 10 上,我也能夠獲得通用的 Windows 10 代碼(在升級的系統上)。

注意:對我來說,盡管原始博客文章指出代碼適用於 Win7 及更高版本,但原始 vbs 腳本返回了錯誤的 Win7 鍵。 所以我總是回退到 Win7 及更低版本的眾所周知的舊方法。

希望能幫助到你。

查看 Windows 產品密鑰查找器。

http://wpkf.codeplex.com/

來源可用。

密鑰存儲在注冊表中,需要使用源中可用的算法進行解碼。

WMI 有一個名為Win32_OperatingSystem的類,其中包含一個名為SerialNumber的屬性:

操作系統產品序列號。

示例:“10497-OEM-0031416-71674”

System.Management命名空間包含允許 .NET 代碼與 WMI 交互的類。

使用mrpeardotnet的答案......

我遇到了RegistryView.Default無法轉換為字符串的錯誤。 我改變了這個:

var key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default);

對此:

var key = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, Environment.MachineName);

它似乎有效。

使用此代碼,您可以找到 Microsoft 產品的產品密鑰。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
namespace MSKeyFinder
{
    public class KeyDecoder
    {
        public enum Key { XP, Office10, Office11 };
        public static byte[] GetRegistryDigitalProductId(Key key)
        {
            byte[] digitalProductId = null;
            RegistryKey registry = null;
            switch (key)
            {
                // Open the XP subkey readonly.
                case Key.XP:
                    registry =
                      Registry.LocalMachine.
                        OpenSubKey(
                          @"SOFTWARE\Microsoft\Windows NT\CurrentVersion",
                            false);
                    break;
                // Open the Office 10 subkey readonly.
                case Key.Office10:
                    registry =
                      Registry.LocalMachine.
                        OpenSubKey(
                          @"SOFTWARE\Microsoft\Office\10.0\Registration\" + 
                          @"{90280409-6000-11D3-8CFE-0050048383C9}",
                          false);
                    // TODO: Open the registry key.
                    break;
                // Open the Office 11 subkey readonly.
                case Key.Office11:
                    // TODO: Open the registry key.
                    break;
            }
            if (registry != null)
            {
                // TODO: For other products, key name maybe different.
                digitalProductId = registry.GetValue("DigitalProductId")
                  as byte[];
                registry.Close();
            }
            return digitalProductId;
        }
        public static string DecodeProductKey(byte[] digitalProductId)
        {
            // Offset of first byte of encoded product key in 
            //  'DigitalProductIdxxx" REG_BINARY value. Offset = 34H.
            const int keyStartIndex = 52;
            // Offset of last byte of encoded product key in 
            //  'DigitalProductIdxxx" REG_BINARY value. Offset = 43H.
            const int keyEndIndex = keyStartIndex + 15;
            // Possible alpha-numeric characters in product key.
            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',
      };
            // Length of decoded product key
            const int decodeLength = 29;
            // Length of decoded product key in byte-form.
            // Each byte represents 2 chars.
            const int decodeStringLength = 15;
            // Array of containing the decoded product key.
            char[] decodedChars = new char[decodeLength];
            // Extract byte 52 to 67 inclusive.
            ArrayList hexPid = new ArrayList();
            for (int i = keyStartIndex; i <= keyEndIndex; i++)
            {
                hexPid.Add(digitalProductId[i]);
            }
            for (int i = decodeLength - 1; i >= 0; i--)
            {
                // Every sixth char is a separator.
                if ((i + 1) % 6 == 0)
                {
                    decodedChars[i] = '-';
                }
                else
                {
                    // Do the actual decoding.
                    int digitMapIndex = 0;
                    for (int j = decodeStringLength - 1; j >= 0; j--)
                    {
                        int byteValue = (digitMapIndex << 8) | (byte)hexPid[j];
                        hexPid[j] = (byte)(byteValue / 24);
                        digitMapIndex = byteValue % 24;
                        decodedChars[i] = digits[digitMapIndex];
                    }
                }
            }
            return new string(decodedChars);
        }
    }
}

參考: http : //www.codeproject.com/Articles/23334/Microsoft-Product-Key-Finder

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM