如何在 C# 中获取 Windows XP 产品密钥?
我想从客户端获取一些像 Windows 密钥这样的密钥。
Erij J. 和其他人在此提到的 Windows 产品密钥查找器和其他解决方案仅适用于 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 代码(在升级的系统上)。
注意:对我来说,原始的 vbs 脚本返回了错误的 Win7 密钥,尽管原始博客文章指出该代码适用于 Win7 及更高版本。所以我总是回退到 Win7 及更低版本的众所周知的旧方法。
希望能帮助到你。
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