improve:设备ID
This commit is contained in:
@@ -46,20 +46,40 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 1. 尝试从主文件读取设备ID
|
// 计算当前设备的硬件指纹
|
||||||
string deviceId = LoadDeviceIdFromFile(DeviceIdFilePath);
|
string currentHardwareFingerprint = GenerateHardwareFingerprint();
|
||||||
if (!string.IsNullOrEmpty(deviceId))
|
|
||||||
|
// 1. 尝试从主文件读取设备ID及其硬件指纹
|
||||||
|
var storedInfo = LoadDeviceIdFromFile(DeviceIdFilePath);
|
||||||
|
if (storedInfo != null && !string.IsNullOrEmpty(storedInfo.DeviceId) && IsValidDeviceId(storedInfo.DeviceId))
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"DeviceIdentifier | 从主文件读取设备ID: {deviceId}");
|
if (!string.IsNullOrEmpty(storedInfo.HardwareFingerprint))
|
||||||
return deviceId;
|
{
|
||||||
|
if (storedInfo.HardwareFingerprint == currentHardwareFingerprint)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"DeviceIdentifier | 从主文件读取设备ID且硬件信息一致: {storedInfo.DeviceId}");
|
||||||
|
return storedInfo.DeviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogHelper.WriteLogToFile("DeviceIdentifier | 检测到当前硬件信息与保存的设备ID不一致,将重新生成设备ID");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("DeviceIdentifier | 检测到旧格式设备ID文件(无硬件信息),将基于当前硬件重新生成设备ID并升级文件格式");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 生成新的设备ID
|
// 2. 基于当前硬件指纹生成新的设备ID
|
||||||
string newDeviceId = GenerateDeviceId();
|
string newDeviceId = GenerateDeviceIdFromFingerprint(currentHardwareFingerprint);
|
||||||
LogHelper.WriteLogToFile($"DeviceIdentifier | 生成新设备ID: {newDeviceId}");
|
LogHelper.WriteLogToFile($"DeviceIdentifier | 生成新设备ID: {newDeviceId}");
|
||||||
|
|
||||||
// 3. 保存到主文件
|
// 3. 保存到主文件(包含硬件指纹)
|
||||||
SaveDeviceIdToFile(DeviceIdFilePath, newDeviceId);
|
var newInfo = new DeviceIdInfo
|
||||||
|
{
|
||||||
|
DeviceId = newDeviceId,
|
||||||
|
HardwareFingerprint = currentHardwareFingerprint
|
||||||
|
};
|
||||||
|
SaveDeviceIdToFile(DeviceIdFilePath, newInfo);
|
||||||
|
|
||||||
return newDeviceId;
|
return newDeviceId;
|
||||||
}
|
}
|
||||||
@@ -79,143 +99,9 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 收集硬件信息
|
// 基于当前硬件指纹生成设备ID
|
||||||
var hardwareInfo = new StringBuilder();
|
string hardwareFingerprint = GenerateHardwareFingerprint();
|
||||||
|
return GenerateDeviceIdFromFingerprint(hardwareFingerprint);
|
||||||
// 使用反射获取硬件信息,避免直接引用System.Management
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 尝试加载System.Management程序集
|
|
||||||
var assembly = Assembly.Load("System.Management");
|
|
||||||
if (assembly != null)
|
|
||||||
{
|
|
||||||
// CPU信息
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var searcherType = assembly.GetType("System.Management.ManagementObjectSearcher");
|
|
||||||
var searcher = Activator.CreateInstance(searcherType, "SELECT ProcessorId FROM Win32_Processor");
|
|
||||||
var getMethod = searcherType.GetMethod("Get");
|
|
||||||
var enumerator = getMethod.Invoke(searcher, null);
|
|
||||||
|
|
||||||
var moveNextMethod = enumerator.GetType().GetMethod("MoveNext");
|
|
||||||
var currentProperty = enumerator.GetType().GetProperty("Current");
|
|
||||||
|
|
||||||
if ((bool)moveNextMethod.Invoke(enumerator, null))
|
|
||||||
{
|
|
||||||
var obj = currentProperty.GetValue(enumerator);
|
|
||||||
var indexer = obj.GetType().GetProperty("Item", new[] { typeof(string) });
|
|
||||||
var processorId = indexer.GetValue(obj, new object[] { "ProcessorId" });
|
|
||||||
hardwareInfo.Append(processorId?.ToString() ?? "");
|
|
||||||
}
|
|
||||||
|
|
||||||
var disposeMethod = searcher.GetType().GetMethod("Dispose");
|
|
||||||
disposeMethod?.Invoke(searcher, null);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
// 主板序列号
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var searcherType = assembly.GetType("System.Management.ManagementObjectSearcher");
|
|
||||||
var searcher = Activator.CreateInstance(searcherType, "SELECT SerialNumber FROM Win32_BaseBoard");
|
|
||||||
var getMethod = searcherType.GetMethod("Get");
|
|
||||||
var enumerator = getMethod.Invoke(searcher, null);
|
|
||||||
|
|
||||||
var moveNextMethod = enumerator.GetType().GetMethod("MoveNext");
|
|
||||||
var currentProperty = enumerator.GetType().GetProperty("Current");
|
|
||||||
|
|
||||||
if ((bool)moveNextMethod.Invoke(enumerator, null))
|
|
||||||
{
|
|
||||||
var obj = currentProperty.GetValue(enumerator);
|
|
||||||
var indexer = obj.GetType().GetProperty("Item", new[] { typeof(string) });
|
|
||||||
var serialNumber = indexer.GetValue(obj, new object[] { "SerialNumber" });
|
|
||||||
hardwareInfo.Append(serialNumber?.ToString() ?? "");
|
|
||||||
}
|
|
||||||
|
|
||||||
var disposeMethod = searcher.GetType().GetMethod("Dispose");
|
|
||||||
disposeMethod?.Invoke(searcher, null);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
// BIOS序列号
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var searcherType = assembly.GetType("System.Management.ManagementObjectSearcher");
|
|
||||||
var searcher = Activator.CreateInstance(searcherType, "SELECT SerialNumber FROM Win32_BIOS");
|
|
||||||
var getMethod = searcherType.GetMethod("Get");
|
|
||||||
var enumerator = getMethod.Invoke(searcher, null);
|
|
||||||
|
|
||||||
var moveNextMethod = enumerator.GetType().GetMethod("MoveNext");
|
|
||||||
var currentProperty = enumerator.GetType().GetProperty("Current");
|
|
||||||
|
|
||||||
if ((bool)moveNextMethod.Invoke(enumerator, null))
|
|
||||||
{
|
|
||||||
var obj = currentProperty.GetValue(enumerator);
|
|
||||||
var indexer = obj.GetType().GetProperty("Item", new[] { typeof(string) });
|
|
||||||
var serialNumber = indexer.GetValue(obj, new object[] { "SerialNumber" });
|
|
||||||
hardwareInfo.Append(serialNumber?.ToString() ?? "");
|
|
||||||
}
|
|
||||||
|
|
||||||
var disposeMethod = searcher.GetType().GetMethod("Dispose");
|
|
||||||
disposeMethod?.Invoke(searcher, null);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
// 主硬盘序列号
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var searcherType = assembly.GetType("System.Management.ManagementObjectSearcher");
|
|
||||||
var searcher = Activator.CreateInstance(searcherType, "SELECT SerialNumber FROM Win32_DiskDrive WHERE MediaType='Fixed hard disk media'");
|
|
||||||
var getMethod = searcherType.GetMethod("Get");
|
|
||||||
var enumerator = getMethod.Invoke(searcher, null);
|
|
||||||
|
|
||||||
var moveNextMethod = enumerator.GetType().GetMethod("MoveNext");
|
|
||||||
var currentProperty = enumerator.GetType().GetProperty("Current");
|
|
||||||
|
|
||||||
if ((bool)moveNextMethod.Invoke(enumerator, null))
|
|
||||||
{
|
|
||||||
var obj = currentProperty.GetValue(enumerator);
|
|
||||||
var indexer = obj.GetType().GetProperty("Item", new[] { typeof(string) });
|
|
||||||
var serialNumber = indexer.GetValue(obj, new object[] { "SerialNumber" });
|
|
||||||
hardwareInfo.Append(serialNumber?.ToString() ?? "");
|
|
||||||
}
|
|
||||||
|
|
||||||
var disposeMethod = searcher.GetType().GetMethod("Dispose");
|
|
||||||
disposeMethod?.Invoke(searcher, null);
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
// 如果硬件信息不足,添加系统信息
|
|
||||||
if (hardwareInfo.Length < 10)
|
|
||||||
{
|
|
||||||
hardwareInfo.Append(Environment.MachineName);
|
|
||||||
hardwareInfo.Append(Environment.UserName);
|
|
||||||
hardwareInfo.Append(Environment.OSVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成哈希
|
|
||||||
using (var sha256 = SHA256.Create())
|
|
||||||
{
|
|
||||||
byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(hardwareInfo.ToString()));
|
|
||||||
string hashString = BitConverter.ToString(hashBytes).Replace("-", "");
|
|
||||||
|
|
||||||
// 取前25个字符,确保唯一性
|
|
||||||
string deviceId = hashString.Substring(0, 25);
|
|
||||||
|
|
||||||
// 添加校验位(第25位)
|
|
||||||
int checksum = 0;
|
|
||||||
for (int i = 0; i < 24; i++)
|
|
||||||
{
|
|
||||||
checksum += Convert.ToInt32(deviceId[i]);
|
|
||||||
}
|
|
||||||
checksum %= 36; // 0-9, A-Z
|
|
||||||
char checksumChar = checksum < 10 ? (char)(checksum + '0') : (char)(checksum - 10 + 'A');
|
|
||||||
|
|
||||||
return deviceId.Substring(0, 24) + checksumChar;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -224,6 +110,157 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成当前设备的硬件指纹字符串(用于生成和校验设备ID)
|
||||||
|
/// </summary>
|
||||||
|
private static string GenerateHardwareFingerprint()
|
||||||
|
{
|
||||||
|
// 收集硬件信息
|
||||||
|
var hardwareInfo = new StringBuilder();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var assembly = Assembly.Load("System.Management");
|
||||||
|
if (assembly != null)
|
||||||
|
{
|
||||||
|
// CPU信息
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var searcherType = assembly.GetType("System.Management.ManagementObjectSearcher");
|
||||||
|
var searcher = Activator.CreateInstance(searcherType, "SELECT ProcessorId FROM Win32_Processor");
|
||||||
|
var getMethod = searcherType.GetMethod("Get");
|
||||||
|
var enumerator = getMethod.Invoke(searcher, null);
|
||||||
|
|
||||||
|
var moveNextMethod = enumerator.GetType().GetMethod("MoveNext");
|
||||||
|
var currentProperty = enumerator.GetType().GetProperty("Current");
|
||||||
|
|
||||||
|
if ((bool)moveNextMethod.Invoke(enumerator, null))
|
||||||
|
{
|
||||||
|
var obj = currentProperty.GetValue(enumerator);
|
||||||
|
var indexer = obj.GetType().GetProperty("Item", new[] { typeof(string) });
|
||||||
|
var processorId = indexer.GetValue(obj, new object[] { "ProcessorId" });
|
||||||
|
hardwareInfo.Append(processorId?.ToString() ?? "");
|
||||||
|
}
|
||||||
|
|
||||||
|
var disposeMethod = searcher.GetType().GetMethod("Dispose");
|
||||||
|
disposeMethod?.Invoke(searcher, null);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
|
// 主板序列号
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var searcherType = assembly.GetType("System.Management.ManagementObjectSearcher");
|
||||||
|
var searcher = Activator.CreateInstance(searcherType, "SELECT SerialNumber FROM Win32_BaseBoard");
|
||||||
|
var getMethod = searcherType.GetMethod("Get");
|
||||||
|
var enumerator = getMethod.Invoke(searcher, null);
|
||||||
|
|
||||||
|
var moveNextMethod = enumerator.GetType().GetMethod("MoveNext");
|
||||||
|
var currentProperty = enumerator.GetType().GetProperty("Current");
|
||||||
|
|
||||||
|
if ((bool)moveNextMethod.Invoke(enumerator, null))
|
||||||
|
{
|
||||||
|
var obj = currentProperty.GetValue(enumerator);
|
||||||
|
var indexer = obj.GetType().GetProperty("Item", new[] { typeof(string) });
|
||||||
|
var serialNumber = indexer.GetValue(obj, new object[] { "SerialNumber" });
|
||||||
|
hardwareInfo.Append(serialNumber?.ToString() ?? "");
|
||||||
|
}
|
||||||
|
|
||||||
|
var disposeMethod = searcher.GetType().GetMethod("Dispose");
|
||||||
|
disposeMethod?.Invoke(searcher, null);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
|
// BIOS序列号
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var searcherType = assembly.GetType("System.Management.ManagementObjectSearcher");
|
||||||
|
var searcher = Activator.CreateInstance(searcherType, "SELECT SerialNumber FROM Win32_BIOS");
|
||||||
|
var getMethod = searcherType.GetMethod("Get");
|
||||||
|
var enumerator = getMethod.Invoke(searcher, null);
|
||||||
|
|
||||||
|
var moveNextMethod = enumerator.GetType().GetMethod("MoveNext");
|
||||||
|
var currentProperty = enumerator.GetType().GetProperty("Current");
|
||||||
|
|
||||||
|
if ((bool)moveNextMethod.Invoke(enumerator, null))
|
||||||
|
{
|
||||||
|
var obj = currentProperty.GetValue(enumerator);
|
||||||
|
var indexer = obj.GetType().GetProperty("Item", new[] { typeof(string) });
|
||||||
|
var serialNumber = indexer.GetValue(obj, new object[] { "SerialNumber" });
|
||||||
|
hardwareInfo.Append(serialNumber?.ToString() ?? "");
|
||||||
|
}
|
||||||
|
|
||||||
|
var disposeMethod = searcher.GetType().GetMethod("Dispose");
|
||||||
|
disposeMethod?.Invoke(searcher, null);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
|
// 主硬盘序列号
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var searcherType = assembly.GetType("System.Management.ManagementObjectSearcher");
|
||||||
|
var searcher = Activator.CreateInstance(searcherType, "SELECT SerialNumber FROM Win32_DiskDrive WHERE MediaType='Fixed hard disk media'");
|
||||||
|
var getMethod = searcherType.GetMethod("Get");
|
||||||
|
var enumerator = getMethod.Invoke(searcher, null);
|
||||||
|
|
||||||
|
var moveNextMethod = enumerator.GetType().GetMethod("MoveNext");
|
||||||
|
var currentProperty = enumerator.GetType().GetProperty("Current");
|
||||||
|
|
||||||
|
if ((bool)moveNextMethod.Invoke(enumerator, null))
|
||||||
|
{
|
||||||
|
var obj = currentProperty.GetValue(enumerator);
|
||||||
|
var indexer = obj.GetType().GetProperty("Item", new[] { typeof(string) });
|
||||||
|
var serialNumber = indexer.GetValue(obj, new object[] { "SerialNumber" });
|
||||||
|
hardwareInfo.Append(serialNumber?.ToString() ?? "");
|
||||||
|
}
|
||||||
|
|
||||||
|
var disposeMethod = searcher.GetType().GetMethod("Dispose");
|
||||||
|
disposeMethod?.Invoke(searcher, null);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hardwareInfo.Length < 10)
|
||||||
|
{
|
||||||
|
hardwareInfo.Append(Environment.MachineName);
|
||||||
|
hardwareInfo.Append(Environment.UserName);
|
||||||
|
hardwareInfo.Append(Environment.OSVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hardwareInfo.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 基于硬件指纹生成25字符的设备ID
|
||||||
|
/// </summary>
|
||||||
|
private static string GenerateDeviceIdFromFingerprint(string hardwareFingerprint)
|
||||||
|
{
|
||||||
|
// 生成哈希
|
||||||
|
using (var sha256 = SHA256.Create())
|
||||||
|
{
|
||||||
|
byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(hardwareFingerprint ?? string.Empty));
|
||||||
|
string hashString = BitConverter.ToString(hashBytes).Replace("-", "");
|
||||||
|
|
||||||
|
// 取前25个字符,确保唯一性
|
||||||
|
string deviceId = hashString.Substring(0, 25);
|
||||||
|
|
||||||
|
// 添加校验位(第25位)
|
||||||
|
int checksum = 0;
|
||||||
|
for (int i = 0; i < 24; i++)
|
||||||
|
{
|
||||||
|
checksum += Convert.ToInt32(deviceId[i]);
|
||||||
|
}
|
||||||
|
checksum %= 36; // 0-9, A-Z
|
||||||
|
char checksumChar = checksum < 10 ? (char)(checksum + '0') : (char)(checksum - 10 + 'A');
|
||||||
|
|
||||||
|
return deviceId.Substring(0, 24) + checksumChar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生成备用设备ID(基于时间戳)
|
/// 生成备用设备ID(基于时间戳)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -282,16 +319,33 @@ namespace Ink_Canvas.Helpers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从文件加载设备ID
|
/// 从文件加载设备ID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static string LoadDeviceIdFromFile(string filePath)
|
private static DeviceIdInfo LoadDeviceIdFromFile(string filePath)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (File.Exists(filePath))
|
if (File.Exists(filePath))
|
||||||
{
|
{
|
||||||
string content = File.ReadAllText(filePath).Trim();
|
string content = File.ReadAllText(filePath).Trim();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var info = JsonConvert.DeserializeObject<DeviceIdInfo>(content);
|
||||||
|
if (info != null && !string.IsNullOrEmpty(info.DeviceId) && IsValidDeviceId(info.DeviceId))
|
||||||
|
{
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
if (IsValidDeviceId(content))
|
if (IsValidDeviceId(content))
|
||||||
{
|
{
|
||||||
return content;
|
return new DeviceIdInfo
|
||||||
|
{
|
||||||
|
DeviceId = content,
|
||||||
|
HardwareFingerprint = null
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -305,7 +359,7 @@ namespace Ink_Canvas.Helpers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 保存设备ID到文件
|
/// 保存设备ID到文件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void SaveDeviceIdToFile(string filePath, string deviceId)
|
private static void SaveDeviceIdToFile(string filePath, DeviceIdInfo info)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -316,7 +370,8 @@ namespace Ink_Canvas.Helpers
|
|||||||
Directory.CreateDirectory(directory);
|
Directory.CreateDirectory(directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
File.WriteAllText(filePath, deviceId);
|
string json = JsonConvert.SerializeObject(info, Formatting.Indented);
|
||||||
|
File.WriteAllText(filePath, json);
|
||||||
|
|
||||||
LogHelper.WriteLogToFile($"DeviceIdentifier | 设备ID已保存到: {filePath}");
|
LogHelper.WriteLogToFile($"DeviceIdentifier | 设备ID已保存到: {filePath}");
|
||||||
}
|
}
|
||||||
@@ -326,6 +381,14 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class DeviceIdInfo
|
||||||
|
{
|
||||||
|
[JsonProperty("deviceId")]
|
||||||
|
public string DeviceId { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("hardwareFingerprint")]
|
||||||
|
public string HardwareFingerprint { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user